Perforce es un sistema de control de versiones muy popular en entornos corporativos. Ha existido desde 1995, conviertiéndolo en el sistema más antiguo cubierto en este capítulo. Como tal, está diseñado con las limitaciones de su día; supone que siempre está conectado a un solo servidor central y sólo se conserva una versión en el disco local. Para estar seguro, sus características y limitaciones son adecuadas para varios problemas específicos, pero hay muchos proyectos que usan Perforce donde Git realmente funcionaría mejor.
Hay dos opciones si desea mezclar el uso de Perforce y Git. La primera que veremos es el puente `’Git Fusion''' de los creadores de Perforce, que le permite exponer los subárboles de su depósito de Perforce como repositorios de lectura y escritura de Git. La segunda es 'git-p4', un puente del lado del cliente que le permite usar Git como un cliente Perforce, sin requerir ninguna reconfiguración del servidor Perforce.
Perforce proporciona un producto llamado ''Git Fusion'' (disponible en http://www.perforce.com/git-fusion), que sincroniza un servidor Perforce con repositorios Git en el lado del servidor.
Para nuestros ejemplos, utilizaremos el método de instalación más fácil para 'Git Fusion': descargando una máquina virtual que ejecuta Perforce Daemon y 'Git Fusion'. Puede obtener la imagen de la máquina virtual desde http://www.perforce.com/downloads/Perforce/20-User, y una vez que haya finalizado la descarga, impórtela en su software de virtualización favorito (utilizaremos VirtualBox).
Al iniciar la máquina por primera vez, le solicita que personalice la contraseña para tres usuarios de Linux (root,` perforce` y git), y proporcione un nombre de instancia, que se puede usar para distinguir esta instalación de otras en el misma red. Cuando todo haya terminado, verás esto:
Debe tomar nota de la dirección IP que se muestra aquí, la usaremos más adelante.
A continuación, crearemos un usuario de Perforce.
Seleccione la opción `Iniciar sesión'' en la parte inferior y presione enter (o SSH en la máquina) e inicie sesión como `root.
Luego use estos comandos para crear un usuario:
$ p4 -p localhost:1666 -u super user -f john
$ p4 -p localhost:1666 -u john passwd
$ exitEl primero abrirá un editor VI para personalizar al usuario, pero puede aceptar los valores predeterminados escribiendo :wq y pulsando enter.
El segundo le pedirá que ingrese una contraseña dos veces.
Eso es todo lo que tenemos que hacer con un intérprete de comandos de shell, así que salga de la sesión.
Lo siguiente que tendrá que hacer es decirle a Git que no verifique los certificados SSL. La imagen de 'Git Fusion' viene con un certificado, pero es para un dominio que no coincidirá con la dirección IP de su máquina virtual, por lo que Git rechazará la conexión HTTPS. Si va a hacer una instalación permanente, consulte el manual de Perforce de 'Git Fusion' para instalar un certificado diferente; para nuestros propósitos de ejemplo, esto será suficiente:
$ export GIT_SSL_NO_VERIFY=trueAhora podemos probar que todo está funcionando.
$ git clone https://10.0.1.254/Talkhouse
Cloning into 'Talkhouse'...
Username for 'https://10.0.1.254': john
Password for 'https://john@10.0.1.254':
remote: Counting objects: 630, done.
remote: Compressing objects: 100% (581/581), done.
remote: Total 630 (delta 172), reused 0 (delta 0)
Receiving objects: 100% (630/630), 1.22 MiB | 0 bytes/s, done.
Resolving deltas: 100% (172/172), done.
Checking connectivity... done.La imagen de la máquina virtual viene equipada con un proyecto de muestra que puede clonar.
Aquí estamos clonando a través de HTTPS, con el usuario john que creamos anteriormente; Git solicita credenciales para esta conexión, pero la caché de credenciales nos permitirá omitir este paso para cualquier solicitud posterior.
Una vez que haya instalado 'Git Fusion', querrá modificar la configuración.Esto es bastante fácil de hacer usando su cliente Perforce favorito; simplemente asigne el directorio //.git-fusion en el servidor Perforce en su espacio de trabajo.La estructura del archivo se ve así:
$ tree
.
├── objects
│ ├── repos
│ │ └── [...]
│ └── trees
│ └── [...]
│
├── p4gf_config
├── repos
│ └── Talkhouse
│ └── p4gf_config
└── users
└── p4gf_usermap
498 directories, 287 filesEl directorio objects es usado internamente por 'Git Fusion' para asignar objetos Perforce a Git y viceversa, no tendrá que meterse con nada allí.
Hay un archivo global p4gf_config en este directorio, así como uno para cada repositorio – estos son los archivos de configuración que determinan cómo se comporta 'Git Fusion'.
Echemos un vistazo al archivo en la raíz:
[repo-creation]
charset = utf8
[git-to-perforce]
change-owner = author
enable-git-branch-creation = yes
enable-swarm-reviews = yes
enable-git-merge-commits = yes
enable-git-submodules = yes
preflight-commit = none
ignore-author-permissions = no
read-permission-check = none
git-merge-avoidance-after-change-num = 12107
[perforce-to-git]
http-url = none
ssh-url = none
[@features]
imports = False
chunked-push = False
matrix2 = False
parallel-push = False
[authentication]
email-case-sensitivity = noNo entraremos en el significado de estos indicadores aquí, pero tenga en cuenta que esto es sólo un archivo de texto con formato INI, muy parecido al que Git usa para la configuración.
Este archivo especifica las opciones globales, que luego pueden ser reemplazadas por archivos de configuración específicos del repositorio, como repos/Talkhouse/p4gf_config.
Si abre este archivo, verá una sección [@repo] con algunas configuraciones que son diferentes de los valores predeterminados globales.
También verá secciones que se ven así:
[Talkhouse-master]
git-branch-name = master
view = //depot/Talkhouse/main-dev/... ...Este es un mapeo entre una rama Perforce y una rama Git.
La sección se puede nombrar como prefiera, siempre que el nombre sea único.
git-branch-name le permite convertir una ruta de depósito que sería engorrosa bajo Git a un nombre más amigable.
La configuración view controla cómo se asocian los archivos de Perforce en el repositorio de Git, usando la sintaxis de mapeo de vista estándar.
Se puede especificar más de un mapeo, como en este ejemplo:
[multi-project-mapping]
git-branch-name = master
view = //depot/project1/main/... project1/...
//depot/project2/mainline/... project2/...De esta manera, si la asignación normal del espacio de trabajo incluye cambios en la estructura de los directorios, puede replicar eso con un repositorio Git.
El último archivo que discutiremos es users/p4gf_usermap, que mapea los usuarios de Perforce a los usuarios de Git, y que quizás ni siquiera necesite.
Al convertir un conjunto de cambios de Perforce a una commit de Git, el comportamiento predeterminado de 'Git Fusion' es buscar al usuario de Perforce y usar la dirección de correo electrónico y el nombre completo almacenados allí para el campo autor/committer en Git.
Al realizar la conversión de otra manera, el valor predeterminado es buscar al usuario de Perforce con la dirección de correo electrónico almacenada en el campo de autoría del commit de Git y enviar el conjunto de cambios como ese usuario (con la aplicación de permisos).
En la mayoría de los casos, este comportamiento funcionará bien, pero considere el siguiente archivo de mapeo:
john john@example.com "John Doe"
john johnny@appleseed.net "John Doe"
bob employeeX@example.com "Anon X. Mouse"
joe employeeY@example.com "Anon Y. Mouse"Cada línea tiene el formato <usuario> <correo electrónico> "<nombre completo>" y crea una sola asignación de usuario. Las dos primeras líneas asignan dos direcciones de correo electrónico distintas a la misma cuenta de usuario de Perforce.
Esto es útil si ha creado 'commits' de Git en varias direcciones de correo electrónico diferentes (o cambia direcciones de correo electrónico), pero quiere que se mapeen al mismo usuario de Perforce.
Al crear una commit de Git a partir de un conjunto de cambios de Perforce, la primera línea que coincide con el usuario de Perforce se utiliza para la información de autoría de Git.
Las últimas dos líneas ocultan los nombres reales y las direcciones de correo electrónico de Bob y Joe de las 'commits' de Git que se crean.
Esto es bueno si desea abrir un proyecto interno de fuente abierta, pero no desea publicar su directorio de empleados en todo el mundo.
Tenga en cuenta que las direcciones de correo electrónico y los nombres completos deben ser únicos, a menos que desee que todos los commit de Git se atribuyan a un único autor ficticio.
Perforce de 'Git Fusion' es un puente de dos vías entre Perforce y el control de versiones de Git. Echemos un vistazo a cómo se siente trabajar desde el lado de Git. Asumiremos que hemos mapeado en el proyecto ``Jam'' usando un archivo de configuración como se muestra arriba, el cual podemos clonar así:
$ git clone https://10.0.1.254/Jam
Cloning into 'Jam'...
Username for 'https://10.0.1.254': john
Password for 'https://ben@10.0.1.254':
remote: Counting objects: 2070, done.
remote: Compressing objects: 100% (1704/1704), done.
Receiving objects: 100% (2070/2070), 1.21 MiB | 0 bytes/s, done.
remote: Total 2070 (delta 1242), reused 0 (delta 0)
Resolving deltas: 100% (1242/1242), done.
Checking connectivity... done.
$ git branch -a
* master
remotes/origin/HEAD -> origin/master
remotes/origin/master
remotes/origin/rel2.1
$ git log --oneline --decorate --graph --all
* 0a38c33 (origin/rel2.1) Create Jam 2.1 release branch.
| * d254865 (HEAD, origin/master, origin/HEAD, master) Upgrade to latest metrowerks on Beos -- the Intel one.
| * bd2f54a Put in fix for jam's NT handle leak.
| * c0f29e7 Fix URL in a jam doc
| * cc644ac Radstone's lynx port.
[...]La primera vez que hace esto, puede tomar algún tiempo. Lo que sucede es que 'Git Fusion' está convirtiendo todos los conjuntos de cambios aplicables en el historial de Perforce en 'commits' de Git. Esto ocurre localmente en el servidor, por lo que es relativamente rápido, pero si tiene un montón de historia, aún puede tomar algo de tiempo. Las recuperaciones posteriores realizan conversiones incrementales, por lo que se parecerá más a la velocidad nativa de Git.
Como puede ver, nuestro repositorio se ve exactamente como cualquier otro repositorio de Git con el que pueda trabajar.
Hay tres ramas, y Git ha creado una rama master local que rastrea origin/master.
Hagamos un poco de trabajo y creemos un par de nuevos 'commits':
# ...
$ git log --oneline --decorate --graph --all
* cfd46ab (HEAD, master) Add documentation for new feature
* a730d77 Whitespace
* d254865 (origin/master, origin/HEAD) Upgrade to latest metrowerks on Beos -- the Intel one.
* bd2f54a Put in fix for jam's NT handle leak.
[...]Tenemos dos nuevos 'commits'. Ahora revisemos si alguien más ha estado trabajando:
$ git fetch
remote: Counting objects: 5, done.
remote: Compressing objects: 100% (3/3), done.
remote: Total 3 (delta 2), reused 0 (delta 0)
Unpacking objects: 100% (3/3), done.
From https://10.0.1.254/Jam
d254865..6afeb15 master -> origin/master
$ git log --oneline --decorate --graph --all
* 6afeb15 (origin/master, origin/HEAD) Update copyright
| * cfd46ab (HEAD, master) Add documentation for new feature
| * a730d77 Whitespace
|/
* d254865 Upgrade to latest metrowerks on Beos -- the Intel one.
* bd2f54a Put in fix for jam's NT handle leak.
[...]¡Parece que alguien lo está!
No lo sabría desde esta vista, pero el commit 6afeb15 se creó realmente utilizando un cliente Perforce.
Sòlo parece otro commit desde el punto de vista de Git, que es exactamente el punto.
Veamos cómo el servidor Perforce trata con un commit de fusión:
$ git merge origin/master
Auto-merging README
Merge made by the 'recursive' strategy.
README | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
$ git push
Counting objects: 9, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (9/9), done.
Writing objects: 100% (9/9), 917 bytes | 0 bytes/s, done.
Total 9 (delta 6), reused 0 (delta 0)
remote: Perforce: 100% (3/3) Loading commit tree into memory...
remote: Perforce: 100% (5/5) Finding child commits...
remote: Perforce: Running git fast-export...
remote: Perforce: 100% (3/3) Checking commits...
remote: Processing will continue even if connection is closed.
remote: Perforce: 100% (3/3) Copying changelists...
remote: Perforce: Submitting new Git commit objects to Perforce: 4
To https://10.0.1.254/Jam
6afeb15..89cba2b master -> masterGit cree que funcionó.
Echemos un vistazo al historial del archivo README desde el punto de vista de Perforce, usando la función de gráfico de revisión de p4v:
Si nunca antes has visto esta interfaz, puede parecer confusa, pero muestra los mismos conceptos que un visor gráfico para el historial de Git.
Estamos viendo el historial del archivo README, por lo que el árbol de directorios en la parte superior izquierda solo muestra ese archivo a medida que aparece en varias ramas.
En la parte superior derecha, tenemos un gráfico visual de cómo se relacionan las diferentes revisiones del archivo, y la vista general de este gráfico se encuentra en la parte inferior derecha.
El resto da a la vista de detalles para la revisión seleccionada (2 en este caso).
Una cosa para notar es que el gráfico se ve exactamente como el del historial de Git.
Perforce no tenía una rama con nombre para almacenar las 'commits' 1 y 2, por lo que creó una rama `anónima'' en el directorio `.git-fusion para contenerla.
Esto también ocurrirá para las ramas nombradas de Git que no se corresponden con una rama de Perforce con nombre (y luego puede asignarlas a una rama de Perforce usando el archivo de configuración).
La mayoría de esto sucede detrás de escena, pero el resultado final es que una persona en un equipo puede estar usando Git, otra puede estar usando Perforce, y ninguno de ellos conocerá la elección del otro.
Si tiene (o puede obtener) acceso a su servidor Perforce, 'Git Fusion' es una excelente manera de hacer que Git y Perforce hablen entre sí. Hay un poco de configuración involucrada, pero la curva de aprendizaje no es muy pronunciada. Esta es una de las pocas secciones en este capítulo donde las precauciones sobre el uso de la potencia total de Git no aparecerán. Eso no quiere decir que Perforce esté contento con todo lo que le arroja – si trata de reescribir la historia que ya ha sido empujada, 'Git Fusion' la rechazará – pero 'Git Fusion' trata muy fuertemente de sentirse nativo. Incluso puede usar submódulos de Git (aunque parecerán extraños a los usuarios de Perforce) y unir ramas (esto se registrará como una integración en el lado de Perforce).
Si no puede convencer al administrador de su servidor para configurar 'Git Fusion', todavía hay una manera de utilizar estas herramientas juntas.
Git-p4 es un puente de dos vías entre Git y Perforce. Funciona completamente dentro de su repositorio Git, por lo que no necesitará ningún tipo de acceso al servidor Perforce (aparte de las credenciales de usuario, por supuesto). Git-p4 no es tan flexible ni una solución completa como 'Git Fusion', pero le permite hacer la mayor parte de lo que le gustaría hacer sin ser invasivo en el entorno del servidor.
|
Note
|
Necesitará la herramienta |
Por ejemplo, ejecutaremos el servidor Perforce desde 'Git Fusion' OVA como se muestra arriba, pero omitiremos el servidor de 'Git Fusion' y pasaremos directamente al control de versión de Perforce.
Para utilizar el cliente de línea de comandos p4 (del cual depende git-p4), deberá establecer un par de variables de entorno:
$ export P4PORT=10.0.1.254:1666
$ export P4USER=johnAl igual que con cualquier cosa en Git, el primer comando es clonar:
$ git p4 clone //depot/www/live www-shallow
Importing from //depot/www/live into www-shallow
Initialized empty Git repository in /private/tmp/www-shallow/.git/
Doing initial import of //depot/www/live/ from revision #head into refs/remotes/p4/masterEsto crea lo que en términos de Git es un clon ``superficial''; sólo la última versión de Perforce se importa a Git; recuerde, Perforce no está diseñado para dar cada revisión a cada usuario. Esto es suficiente para usar Git como cliente de Perforce, pero para otros fines no es suficiente.
Una vez que está terminado, tenemos un repositorio de Git completamente funcional:
$ cd myproject
$ git log --oneline --all --graph --decorate
* 70eaf78 (HEAD, p4/master, p4/HEAD, master) Initial import of //depot/www/live/ from the state at revision #headTenga en cuenta que hay un control remoto ``p4'' para el servidor de Perforce, pero todo lo demás parece un clon estándar. En realidad, eso es un poco engañoso; no hay realmente un control remoto allí.
$ git remote -vNo hay controles remotos en este repositorio en lo absoluto.
Git-p4 ha creado algunas refs para representar el estado del servidor, y se ven como refs remotas para git log, pero no son administradas por Git, y no puede presionarlas.
De acuerdo, hagamos un poco de trabajo. Supongamos que ha hecho algún progreso en una característica muy importante y está listo para mostrársela al resto de su equipo.
$ git log --oneline --all --graph --decorate
* 018467c (HEAD, master) Change page title
* c0fb617 Update link
* 70eaf78 (p4/master, p4/HEAD) Initial import of //depot/www/live/ from the state at revision #headHemos realizado dos nuevos 'commits' que estamos listos para enviar al servidor de Perforce. Comprobemos si alguien más estaba trabajando hoy:
$ git p4 sync
git p4 sync
Performing incremental import into refs/remotes/p4/master git branch
Depot paths: //depot/www/live/
Import destination: refs/remotes/p4/master
Importing revision 12142 (100%)
$ git log --oneline --all --graph --decorate
* 75cd059 (p4/master, p4/HEAD) Update copyright
| * 018467c (HEAD, master) Change page title
| * c0fb617 Update link
|/
* 70eaf78 Initial import of //depot/www/live/ from the state at revision #headParece que sí, ya que master y p4/master han divergido.
El sistema de ramificación de Perforce es nada similar al de Git, por lo que enviar 'commits' de fusión no tiene ningún sentido.
Git-p4 recomienda que haga rebase de sus 'commits', e incluso viene con un atajo para hacerlo:
$ git p4 rebase
Performing incremental import into refs/remotes/p4/master git branch
Depot paths: //depot/www/live/
No changes to import!
Rebasing the current branch onto remotes/p4/master
First, rewinding head to replay your work on top of it...
Applying: Update link
Applying: Change page title
index.html | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)Probablemente pueda parecer simple desde la salida, pero git p4 rebase es un atajo para` git p4 sync` seguido de git rebase p4/master.
Es un poco más inteligente que eso, especialmente cuando se trabaja con múltiples ramas, pero esta es una buena aproximación.
Ahora nuestra historia es lineal nuevamente y estamos listos para enviar nuestros cambios de vuelta en Perforce.
El comando git p4 submit intentará crear una nueva revisión de Perforce para cada commit de Git entre p4/master y master.
Al ejecutarlo, nos deja en nuestro editor favorito, y los contenidos del archivo se ven algo así:
# A Perforce Change Specification.
#
# Change: The change number. 'new' on a new changelist.
# Date: The date this specification was last modified.
# Client: The client on which the changelist was created. Read-only.
# User: The user who created the changelist.
# Status: Either 'pending' or 'submitted'. Read-only.
# Type: Either 'public' or 'restricted'. Default is 'public'.
# Description: Comments about the changelist. Required.
# Jobs: What opened jobs are to be closed by this changelist.
# You may delete jobs from this list. (New changelists only.)
# Files: What opened files from the default changelist are to be added
# to this changelist. You may delete files from this list.
# (New changelists only.)
Change: new
Client: john_bens-mbp_8487
User: john
Status: new
Description:
Update link
Files:
//depot/www/live/index.html # edit
######## git author ben@straub.cc does not match your p4 account.
######## Use option --preserve-user to modify authorship.
######## Variable git-p4.skipUserNameCheck hides this message.
######## everything below this line is just the diff #######
--- //depot/www/live/index.html 2014-08-31 18:26:05.000000000 0000
+++ /Users/ben/john_bens-mbp_8487/john_bens-mbp_8487/depot/www/live/index.html 2014-08-31 18:26:05.000000000 0000
@@ -60,7 +60,7 @@
</td>
<td valign=top>
Source and documentation for
-<a href="http://www.perforce.com/jam/jam.html">
+<a href="jam.html">
Jam/MR</a>,
a software build tool.
</td>Esto es principalmente el mismo contenido que vería al ejecutar p4 submit, excepto las cosas al final que git-p4 ha incluido amablemente.
Git-p4 intenta honrar su configuración de Git y Perforce individualmente cuando tiene que proporcionar un nombre para un commit o un conjunto de cambios, pero en algunos casos usted quiere anularla.
Por ejemplo, si el commit de Git que está importando fue escrito por un colaborador que no tiene una cuenta de usuario de Perforce, es posible que aún quiera que el conjunto de cambios resultante tenga el aspecto de que lo escribió él (y no usted).
Git-p4 ha importado amablemente el mensaje de la confirmación de Git como el contenido de este conjunto de cambios de Perforce, por lo que todo lo que tenemos que hacer es guardar y salir, dos veces (una para cada confirmación). El resultante del shell será algo como esto:
$ git p4 submit
Perforce checkout for depot path //depot/www/live/ located at /Users/ben/john_bens-mbp_8487/john_bens-mbp_8487/depot/www/live/
Synchronizing p4 checkout...
... - file(s) up-to-date.
Applying dbac45b Update link
//depot/www/live/index.html#4 - opened for edit
Change 12143 created with 1 open file(s).
Submitting change 12143.
Locking 1 files ...
edit //depot/www/live/index.html#5
Change 12143 submitted.
Applying 905ec6a Change page title
//depot/www/live/index.html#5 - opened for edit
Change 12144 created with 1 open file(s).
Submitting change 12144.
Locking 1 files ...
edit //depot/www/live/index.html#6
Change 12144 submitted.
All commits applied!
Performing incremental import into refs/remotes/p4/master git branch
Depot paths: //depot/www/live/
Import destination: refs/remotes/p4/master
Importing revision 12144 (100%)
Rebasing the current branch onto remotes/p4/master
First, rewinding head to replay your work on top of it...
$ git log --oneline --all --graph --decorate
* 775a46f (HEAD, p4/master, p4/HEAD, master) Change page title
* 05f1ade Update link
* 75cd059 Update copyright
* 70eaf78 Initial import of //depot/www/live/ from the state at revision #headEl resultado es como si hubiéramos hecho un git push, que es la analogía más cercana a lo que realmente sucedió.
Tenga en cuenta que durante este proceso, cada commit de Git se convierte en un conjunto de cambios de Perforce; si desea aplastarlos en un único conjunto de cambios, puede hacerlo con una rebase interactiva antes de ejecutar git p4 submit.
También tenga en cuenta que los hashes SHA-1 de todas las 'commits' que se enviaron como conjuntos de cambios han cambiado; esto es porque git-p4 agrega una línea al final de cada confirmación que convierte:
$ git log -1
commit 775a46f630d8b46535fc9983cf3ebe6b9aa53145
Author: John Doe <john@example.com>
Date: Sun Aug 31 10:31:44 2014 -0800
Change page title
[git-p4: depot-paths = "//depot/www/live/": change = 12144]¿Qué sucede si intenta enviar una commit de fusión?
Hagamos un intento.
Esta es la situación en la que nos hemos metido:
$ git log --oneline --all --graph --decorate
* 3be6fd8 (HEAD, master) Correct email address
* 1dcbf21 Merge remote-tracking branch 'p4/master'
|\
| * c4689fc (p4/master, p4/HEAD) Grammar fix
* | cbacd0a Table borders: yes please
* | b4959b6 Trademark
|/
* 775a46f Change page title
* 05f1ade Update link
* 75cd059 Update copyright
* 70eaf78 Initial import of //depot/www/live/ from the state at revision #headLa historia de Git y Perforce divergen después de 775a46f.
El lado de Git tiene dos 'commits', luego un commit de fusión con la cabeza de Perforce, y luego otro commit.
Vamos a tratar de enviar estos sobre un único conjunto de cambios en el lado de Perforce.
Veamos qué pasaría si intentáramos enviar ahora:
$ git p4 submit -n
Perforce checkout for depot path //depot/www/live/ located at /Users/ben/john_bens-mbp_8487/john_bens-mbp_8487/depot/www/live/
Would synchronize p4 checkout in /Users/ben/john_bens-mbp_8487/john_bens-mbp_8487/depot/www/live/
Would apply
b4959b6 Trademark
cbacd0a Table borders: yes please
3be6fd8 Correct email addressLa bandera -n es la abreviatura de --dry-run, que intenta informar qué pasaría si el comando submit se ejecutara de manera real.
En este caso, parece que estaríamos creando tres conjuntos de cambios de Perforce, que corresponden a las tres confirmaciones que no se fusionan y que todavía no existen en el servidor Perforce.
Eso suena exactamente como lo que queremos, veamos cómo resulta:
$ git p4 submit
[…]
$ git log --oneline --all --graph --decorate
* dadbd89 (HEAD, p4/master, p4/HEAD, master) Correct email address
* 1b79a80 Table borders: yes please
* 0097235 Trademark
* c4689fc Grammar fix
* 775a46f Change page title
* 05f1ade Update link
* 75cd059 Update copyright
* 70eaf78 Initial import of //depot/www/live/ from the state at revision #headNuestra historia se volvió lineal, como si hubiéramos vuelto a hacer rebase antes de enviar (que de hecho es exactamente lo que sucedió).
Esto significa que puede ser libre para crear, trabajar, deshacer y fusionar ramas en el lado de Git sin miedo a que su historia se vuelva incompatible con Perforce.
Si puede volver a establecerla, puede contribuir a un servidor de Perforce.
Si su proyecto Perforce tiene múltiples ramas, no está sin suerte; git-p4 puede manejar eso de una manera que lo haga sentir como Git.
Digamos que su depósito Perforce se presenta así:
//depot
└── project
├── main
└── devY digamos que tiene una rama dev, que tiene una especificación de vista que se ve así:
//depot/project/main/... //depot/project/dev/...Git-p4 puede detectar automáticamente esa situación y hacer lo correcto:
$ git p4 clone --detect-branches //depot/project@all
Importing from //depot/project@all into project
Initialized empty Git repository in /private/tmp/project/.git/
Importing revision 20 (50%)
Importing new branch project/dev
Resuming with change 20
Importing revision 22 (100%)
Updated branches: main dev
$ cd project; git log --oneline --all --graph --decorate
* eae77ae (HEAD, p4/master, p4/HEAD, master) main
| * 10d55fb (p4/project/dev) dev
| * a43cfae Populate //depot/project/main/... //depot/project/dev/....
|/
* 2b83451 Project initTenga en cuenta el especificador `@all'' en la ruta de depósito; eso le dice a `git-p4 que clone no sólo el último conjunto de cambios para ese subárbol, sino todos los conjuntos de cambios que alguna vez hayan tocado esas rutas.
Esto está más cerca del concepto de clon de Git, pero si está trabajando en un proyecto con una larga historia, podría llevar un tiempo.
La bandera --detect-branches le dice a git-p4 que use las especificaciones de rama de Perforce para asignar las ramas a las refs de Git.
Si estas asignaciones no están presentes en el servidor Perforce (que es una forma perfectamente válida de usar Perforce), puede indicar a git-p4 cuáles son las asignaciones de bifurcación y obtendrá el mismo resultado:
$ git init project
Initialized empty Git repository in /tmp/project/.git/
$ cd project
$ git config git-p4.branchList main:dev
$ git clone --detect-branches //depot/project@all .Estableciendo la variable de configuración git-p4.branchList en main:dev le dice a git-p4 que main'' y dev'' son ambas ramas, y la segunda es hija de la primera.
Si ahora aplicamos git checkout -b dev p4/project/dev y realizamos algunas 'commits', git-p4 es lo suficientemente inteligente para apuntar a la rama correcta cuando hacemos git p4 submit.
Desafortunadamente, git-p4 no puede mezclar clones superficiales y ramas múltiples; si tiene un gran proyecto y quiere trabajar en más de una rama, tendrá que hacer 'git p4 clone' una vez por cada rama a la que quiera enviar.
Para crear o integrar ramas, deberá usar un cliente Perforce.
git-p4 sólo puede sincronizar y enviar a las ramas existentes, y sólo puede hacerlo sobre un conjunto de cambios lineal a la vez.
Si combina dos ramas en Git e intenta enviar el nuevo conjunto de cambios, todo lo que se registrará será un conjunto de cambios de archivos; los metadatos sobre qué ramas están involucradas en la integración se perderán.
git-p4 hace posible usar un flujo de trabajo de Git con un servidor Perforce, y es bastante bueno en eso.
Sin embargo, es importante recordar que Perforce está a cargo de la fuente y que sólo está usando Git para trabajar localmente.
Tenga mucho cuidado al compartir 'commits' de Git; si tiene un control remoto que utilizan otras personas, no envíe ningun commit que aún no se haya enviado al servidor de Perforce.
Si desea mezclar libremente el uso de Perforce y Git como clientes para el control de código fuente, y puede convencer al administrador del servidor para que lo instale, 'Git Fusion' hace que Git sea un cliente de control de versiones de primera clase para un servidor Perforce.

