Perforce — очень распространённая система контроля версий в корпоративной среде. Она появилась в 1995 году, что делает её самой старой системой контроля версий, рассматриваемой в этой главе. Perforce разработан в духе тех времён; он предполагает постоянное подключение к центральному серверу, а локально хранится одна-единственная версия файлов. На самом деле, его возможности, как и ограничения, разрабатывались для решения вполне конкретных проблем; хотя многие проекты, использующие Perforce сегодня, выиграли бы от перехода на Git.
Существует два варианта совместного использования Git и Perforce.
Первый — Git Fusion от разработчиков Perforce — позволяет выставлять поддеревья Perforce-депо в качестве удалённых Git репозиториев.
Второй — git-p4
— клиентская обёртка над Perforce для Git; она не требует дополнительной настройки Perforce сервера.
У создателей Perforce есть продукт, именуемый Git Fusion (доступен на http://www.perforce.com/git-fusion), который синхронизирует Perforce сервер с Git репозиторием на стороне сервера.
Для примера мы воспользуемся простейшим способом настройки Git Fusion — подготовленным образом для виртуальной машины с предустановленным Perforce демоном и собственно Git Fusion. Вы можете скачать образ на http://www.perforce.com/downloads/Perforce/20-User, а затем импортировать его в ваше любимое средство виртуализации (мы будем использовать VirtualBox).
Во время первого запуска вам потребуется сконфигурировать пароли трёх Linux пользователей (root
, perforce
и git
) и имя хоста, которое будет идентифицировать компьютер в сети.
По окончании вы увидите следующее:
Запомните IP адрес, он пригодится в будущем.
Далее, создадим пользователя Perforce.
Выберите внизу опцию «Login» и нажмите Enter
(или используйте SSH) и войдите как пользователь root
.
Используйте приведённые ниже команды, чтобы создать пользователя:
$ p4 -p localhost:1666 -u super user -f john
$ p4 -p localhost:1666 -u john passwd
$ exit
Первая команда откроет редактор для уточнения данных пользователя, но вы можете принять настройки по умолчанию, введя :wq
и нажав Enter
.
Вторая команда дважды попросит ввести пароль.
Это всё, что требовалось выполнить в оболочке ОС, можете завершить сессию.
Следующим шагом необходимо запретить Git проверять SSL сертификаты. Хотя виртуальная машина Git Fusion поставляется с сертификатом, он не привязан к домену и IP адресу виртуальной машины, так что Git будет отвергать соединения как небезопасные. Если вы собираетесь использовать эту виртуальную машину на постоянной основе, обратитесь к руководству по Git Fusion, чтобы узнать, как установить другой сертификат; для тестов же хватит следующего:
$ export GIT_SSL_NO_VERIFY=true
Теперь можете проверить что всё работает.
$ git clone https://10.0.1.254/Talkhouse
Cloning into 'Talkhouse'...
Username for 'https://10.0.1.254': john
Password for 'https://[email protected]':
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.
На виртуальной машине уже настроен проект, который вы можете клонировать.
Мы клонируем репозиторий по HTTPS протоколу, используя ранее созданного пользователя john
; Git спросит пароль, но менеджер паролей запомнит его для последующих запросов.
После установки Git Fusion вы, возможно, захотите настроить его.
Это относительно несложно сделать, используя ваш любимый Perforce клиент; просто отобразите каталог //.git-fusion
на Perforce сервере в ваше рабочее пространство.
Структура файлов приведена ниже:
$ tree
.
├── objects
│ ├── repos
│ │ └── [...]
│ └── trees
│ └── [...]
│
├── p4gf_config
├── repos
│ └── Talkhouse
│ └── p4gf_config
└── users
└── p4gf_usermap
498 directories, 287 files
Каталог objects
используется Git Fusion для отображения объектов Perforce в Git и наоборот, вам не следует ничего здесь трогать.
Внутри расположен глобальный конфигурационный файл p4gf_config
, а также по одному такому же файлу для каждого репозитория — эти файлы и определяют поведение Git Fusion.
Заглянем в тот, что в корне:
[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 = no
Мы не будем вдаваться в назначение каждой опции, просто обратите внимание, что это обыкновенный INI файл, подобный тем, что использует Git для конфигурации.
Файл, рассмотренный выше, задаёт глобальные опции, которые могут быть переопределены внутри специфичных для репозитория файлов конфигурации, типа repos/Talkhouse/p4gf_config
.
Если откроете этот файл, увидите секцию [@repo]
, переопределяющую некоторые глобальные настройки.
Также, внутри есть секции, подобные этой:
[Talkhouse-master]
git-branch-name = master
view = //depot/Talkhouse/main-dev/... ...
Они задают соответствие между ветками Perforce и ветками Git.
Названия таких секций могут быть произвольными; главное, чтобы они оставались уникальными.
git-branch-name
позволяет преобразовать пути внутри депо, которые смотрелись бы непривычно для Git пользователей.
Параметр view
управляет отображением Perforce файлов на Git репозиторий; используется стандартный синтаксис отображения видов.
Может быть задано более одного отображения, как в примере ниже:
[multi-project-mapping]
git-branch-name = master
view = //depot/project1/main/... project1/...
//depot/project2/mainline/... project2/...
Таким образом, если ваше отображение включает изменения в структуре каталогов, вы можете реплицировать эти изменения здесь.
Последний файл, который мы обсудим, это users/p4gf_usermap
; в нём задаётся отображение пользователей Perforce на пользователей Git.
Возможно, вам не пригодится этот файл.
Когда Git Fusion преобразовывает набор изменений Perforce в Git коммит, он находит пользователя в этом файле и использует хранящиеся здесь адрес электронной почты и полное имя для заполнения полей «автор» и «применяющий изменения» в Git. При обратном процессе ищется пользователь Perforce с адресом электронной почты из поля «автор» Git коммитов и используется далее для изменения.
В большинстве случаев это нормальное поведение, но что будет, если соответствия выглядят так:
john [email protected] "John Doe"
john [email protected] "John Doe"
bob [email protected] "Anon X. Mouse"
joe [email protected] "Anon Y. Mouse"
Каждая строка имеет формат <user> <email> "<full name>"
и задаёт соответствие для одного пользователя.
Первые две строчки отображают два разных адреса электронной почты на одного и того же пользователя.
Это может быть полезным если вы фиксировали изменения в Git, используя разные адреса, или если вы поменяли адрес, но хотите отобразить эти изменения на одного и того же Perforce пользователя.
При создании Git коммитов Perforce используется информация из первой совпавшей строки.
Последние две строки скрывают настоящие имена Боба и Джо в созданных Git коммитах. Это может быть полезным, если вы хотите отдать внутренний проект в open-source, но не хотите раскрывать информацию о сотрудниках. Адреса электронной почты и полные имена должны быть уникальными если вы хотите хоть как-то различать авторов в полученном Git репозитории.
Perforce Git Fusion — это двунаправленный «мост» между Perforce и Git. Давайте посмотрим, как выглядит работа со стороны Git. Предполагается, что мы настроили отображение проекта «Jam», используя приведённую выше конфигурацию. Тогда мы можем клонировать его:
$ git clone https://10.0.1.254/Jam
Cloning into 'Jam'...
Username for 'https://10.0.1.254': john
Password for 'https://[email protected]':
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.
[...]
В первый раз этот процесс может занять некоторое время. Git Fusion преобразовывает все наборы изменений Perforce в Git коммиты. Данные преобразуются локально на сервере, так что это вполне быстрый процесс; тем не менее, он может слегка затянуться, если у вас большая история изменений. Последующие скачивания требуют лишь инкрементального преобразования данных, таким образом скорость будет сравнима со скоростью работы обычного Git сервера.
Как видите, наш репозиторий выглядит так же, как выглядел бы любой другой Git репозиторий.
В нём три ветки и Git предусмотрительно создал локальную ветку master
, отслеживающую origin/master
.
Давайте немного поработаем и зафиксируем изменения:
# ...
$ 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.
[...]
Теперь у нас два новых коммита. Проверим, какие изменения внесли другие:
$ 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.
[...]
Кто-то успел отправить свои изменения раньше нас!
Конечно, из приведённого вывода команды git fetch
не видно, но на самом деле коммит с SHA-1 6afeb15
был создан Perforce клиентом.
Он выглядит так же, как и любой другой коммит, и это именно то, для чего создан Git Fusion.
Давайте посмотрим, как Perforce обработает коммит слияния:
$ 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 -> master
Со стороны Git всё работает как положено.
Давайте посмотрим на историю файла README
со стороны Perforce, используя p4v
:
Если вы ни разу не работали с Perforce это окно может показаться вам запутанным, но его концепция аналогичная gitk
.
Мы просматриваем историю файла README
, так что дерево каталогов слева вверху показывает этот файл в разных ветках.
Справа вверху мы видим граф зависимости разных ревизий файла, справа внизу этот же граф показан целиком для быстрого ориентирования.
Оставшаяся часть окна отображает детали выбранной ревизии (в нашем случае это ревизия 2
).
Граф выглядит в точности как в Git.
У Perforce не было именованной ветки для сохранения коммитов 1
и 2
, так что он создал «анонимную» ветку в каталоге .git-fusion
.
Git Fusion поступит так же для именованных Git веток не соответствующих веткам в Perforce, но вы можете задать соответствие в конфигурационном файле.
Большинство происходящей магии скрыто от посторонних глаз, а в результате кто-то в команде может использовать Git, кто-то — Perforce и никто не будет подозревать о выборе других.
Если у вас есть (или вы можете получить) доступ к Perforce серверу, Git Fusion — это прекрасный способ подружить Git и Perforce. Конечно, требуется небольшая работа напильником, но в целом всё довольно интуитивно и просто. Это один из немногих разделов в этой главе, где мы не будем предупреждать вас об опасности использования всей функциональности Git. Но Perforce не всеяден: если вы попытаетесь переписать опубликованную историю, Git Fusion отклонит изменения. Тем не менее, Git Fusion будет стараться изо всех сил, чтобы не нарушать ваших привычек при работе с Git. Вы даже можете использовать подмодули Git (хотя они и будут выглядеть странными для Perforce пользователей) и сливать ветки (на стороне Perforce это будет выглядеть как интеграция).
И даже в том случае, если вы не можете уговорить администратора настроить Git Fusion есть способ использовать Git и Perforce вместе.
Git-p4 — это двусторонний мост между Git и Perforce. Он работает на стороне клиента, так что вам не нужен будет доступ к Perforce серверу (разумеется, вам по-прежнему понадобятся логин и пароль). Git-p4 не так гибок и полнофункционален, как Git Fusion, но он позволяет совершать большинство необходимых действий.
Note
|
Исполняемый файл |
Мы будем использовать описанный выше образ виртуальной машины Git Fusion, но мы будем напрямую обращаться к Perforce, минуя Git Fusion.
Для того, чтобы использовать команду p4
(от которой зависит git-p4
), вам нужно будет установить следующие переменные окружения:
$ export P4PORT=10.0.1.254:1666
$ export P4USER=john
Как обычно при работе с Git, первая команда — это клонирование:
$ 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/master
В терминах Git мы получим так называемую «поверхностную» копию: выкачивается лишь последняя ревизия. Помните, Perforce не предназначен для раздачи всех ревизий всем пользователям. Этого достаточно, чтобы использовать Git как Perforce клиент, но этого недостаточно для других задач.
Как только клонирование завершится, у нас будет Git репозиторий:
$ 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 #head
Обратите внимание на наличие удалённого репозитория p4
, соответствующего Perforce серверу; всё остальное выглядит как обычный клонированный репозиторий.
Но давайте присмотримся повнимательней: на самом деле нет никакого удалённого репозитория!
$ git remote -v
В этом репозитории нет удалённых серверов.
git-p4
создал несколько ссылок для представления состояния на сервере, и они выглядят как удалённый сервер для git log
, но таковым не являются и вы не можете отправлять изменения в них.
Что ж, приступим к работе. Предположим, вы сделали несколько изменений для очень важной фичи и готовы показать свои наработки остальным членам команды.
$ 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 #head
Мы подготовили два коммита для отправки на Perforce сервер. Давайте посмотрим, успели ли другие члены команды проделать какую-либо работу:
$ 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 #head
Кажется, успели: master
и p4/master
разошлись.
Система ветвления в Perforce абсолютно непохожа на Git, отправка слияний в Perforce не имеет смысла.
git-p4
рекомендует перемещать коммиты и даже предоставляет команду для этого:
$ 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(-)
Вы, возможно, скажете что git p4 rebase
это всего лишь сокращение для git p4 sync
с последующим git rebase p4/master
.
На самом деле, эта команда немного умнее, особенно при работе с несколькими ветками, но догадка вполне верна.
Теперь наша история снова линейна и мы готовы отправить изменения в Perforce.
Команда git p4 submit
попытается создать новые Perforce ревизии для всех коммитов в Git между p4/master
и master
.
Её запуск откроет ваш любимый редактор с примерно таким содержимым:
# 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 [email protected] 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>
Это практически те же данные, что вы увидели бы, запустив p4 submit
, за исключением нескольких строк в конце, любезно вставленных git-p4
.
git-p4
старается учитывать Git и Perforce настройки когда нужно предоставить имя для коммита, но в некоторых случаях вы захотите изменить его.
Например, если коммит в Git был создан человеком, у которого нет Perforce аккаунта, вы всё равно захотите сделать автором коммита его, а не себя.
git-p4
вставил сообщение из коммита Git в содержимое набора изменений Perforce, так что всё что нам остаётся сделать — это дважды сохранить и закрыть редактор (по одному разу на каждый коммит).
В результате мы получим такой вывод:
$ 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 #head
Выглядит так, словно мы только что выполнили git push
, что на самом деле очень близко к тому, что произошло.
Обратите внимание, что во время этого процесса каждый коммит в Git превращается в отдельный набор изменений Perforce; если вы хотите слепить их воедино, вы можете сделать это с помощью интерактивного переноса коммитов до выполнения git p4 submit
.
Ещё один важный момент: SHA-1 хеши коммитов, превращённых в наборы изменений Perforce изменились: это произошло из-за того, что git-p4
добавил строку в конец каждого сообщения:
$ git log -1
commit 775a46f630d8b46535fc9983cf3ebe6b9aa53145
Author: John Doe <[email protected]>
Date: Sun Aug 31 10:31:44 2014 -0800
Change page title
[git-p4: depot-paths = "//depot/www/live/": change = 12144]
Что произойдёт если вы попробуете отправить коммит слияния? Давайте попробуем. Допустим, мы имеем такую историю:
$ 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 #head
История в Git разошлась с Perforce на коммит 775a46f
.
В Git мы имеем два дополнительные коммита, затем слияние с состоянием Perforce, затем ещё один коммит.
Мы собираемся отправить эту историю в Perforce.
Давайте посмотрим, что произойдёт:
$ 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 address
Флаг -n
— это сокращение для --dry-run
, который, в свою очередь, пытается вывести результат выполнения отправки, как если бы отправка на самом деле произошла.
В этом случае, похоже мы создадим три ревизии в Perforce, по одной для каждой не являющейся слиянием коммита в Git.
Звучит логично, давайте посмотрим что произойдёт на самом деле:
$ 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 #head
История стала линейной, словно мы переместили изменения перед отправкой (что на самом деле и произошло). Это означает, что вы можете свободно создавать ветки в Git, работать в них, сливать их, не боясь, что ваша история станет несовместима с Perforce. Если вы можете переместить изменения, вы можете отправить их на Perforce сервер.
Если в вашем Perforce проекте несколько веток, не переживайте: git-p4
может организовать работу с ними, не сложнее, чем с обычными Git ветками.
Предположим, ваш Perforce репозиторий имеет следующую структуру:
//depot
└── project
├── main
└── dev
Также предположим, что ветка dev
настроена следующим образом:
//depot/project/main/... //depot/project/dev/...
git-p4
может автоматически распознать эту ситуацию и выполнить нужные действия:
$ 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 init
Обратите внимание на @all
в пути; она говорит git-p4
клонировать не только последнюю ревизию для указанного поддерева, но все ревизии, затрагивающие указанные пути.
Это ближе к оригинальной концепции клонирования в Git, но если вы работаете с большим репозиторием, это может занять некоторое время.
Флаг --detect-branches
указывает git-p4
использовать настройки веток Perforce для отображения на Git ветки.
Если же таких настроек на Perforce сервере нет (что вполне корректно для Perforce), вы можете указать их git-p4
вручную, получив аналогичный результат:
$ 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 .
Задав конфигурационный параметр git-p4.branchList
равным main:dev
мы указали git-p4
, что «main» и «dev» — это ветки, и что вторая является потомком первой.
Если мы теперь выполним git checkout -b dev p4/project/dev
и зафиксируем в ветке dev
некоторые изменения, git-p4
будет достаточно смышлёным, чтобы догадаться, в какую ветку отправлять изменения при выполнении git p4 submit
.
К сожалению, git-p4
не позволяет использовать несколько веток в поверхностных копиях репозиториев; если у вас есть большой проект и вы хотите работать более чем в одной ветке, вам придётся выполнять git p4 clone
для каждой ветки, в которую вы хотите отправлять изменения.
Для создания и интеграции веток вам нужно будет использовать Perforce клиент.
git-p4
может только забирать изменения из Perforce и отправлять линейную историю обратно.
Если вы произведёте слияние двух веток в Git и отправите изменения в Perforce, сохранятся лишь данные об изменении файлов, все метаданные об исходных ветках, участвующих в интеграции, будут потеряны.
git-p4
позволяет использовать Git для работы с Perforce и он достаточно хорош в этом.
Тем не менее, не стоит забывать, что источником данных по-прежнему остаётся Perforce, а Git используется лишь для локальной работы.
Будьте осторожны с публикацией Git коммитов: если у вас есть удалённый репозиторий, который используют другие люди, не публикуйте в нём коммиты, не отправленные на Perforce сервер.
Если вы хотите свободно смешивать Git и Perforce для контроля версий, уговорите администратора установить Git Fusion — он позволяет использовать Git в качестве полноценного клиента для Perforce сервера.