Uso o Perforce há vários anos. Eu gostaria de passar a usar git para meu código pessoal, mas todos os tutoriais de git que eu vi presumem que você é um controle de fonte completo n00b (o que os torna incrivelmente tediosos) ou que você está acostumado svn (que eu não sou).
Eu conheço o p4, e também entendo a ideia por trás de um sistema de controle de origem distribuído (então não preciso de um discurso de vendas, obrigado). O que eu gostaria é uma tabela de tradução do comando p4 para comandos git equivalentes, bem como os comandos "não podem viver sem" que não têm equivalente p4.
Como suspeito que cada usuário p4 usa um subconjunto diferente de p4, aqui estão algumas das coisas que faço regularmente no p4 que gostaria de poder fazer no git e que não são imediatamente óbvias pelos documentos que li :
- crie várias changelists pendentes em um único cliente. (
p4 change
) - editar uma lista de alterações pendente. (também
p4 change
) - veja uma lista de todas as minhas changelists pendentes (
p4 changes -s pending
) - lista de todos os arquivos alterados em meu cliente (
p4 opened
) ou em uma lista de alterações pendente (p4 describe
) - veja um diff de uma changelist pendente (eu uso um script wrapper para isso que usa
p4 diff
ep4 describe
) - para um determinado arquivo, veja quais changelists enviadas afetaram quais linhas (
p4 annotate
) - para um determinado arquivo, veja uma lista das descrições das changelists que afetaram o arquivo (
p4 log
) - enviar uma changelist pendente (
p4 submit -c
) - abortar uma changelist pendente (
p4 revert
)
Muitos deles giram em torno de "changelists". "changelist" é a terminologia p4. Qual é o termo equivalente do git?
Parece que branches podem ser o que os usuários git usam no lugar do que o p4 chama de changelists. Um pouco confuso, já que p4 também tem algo chamado de branch, embora eles pareçam ser conceitos apenas vagamente relacionados. (Embora eu sempre tenha pensado que o conceito de ramificação do p4 era muito estranho, é diferente mais uma vez do conceito RCS clássico de ramificação.)
Enfim ... Não tenho certeza de como realizar o que normalmente faço em changelists p4 com branches do git. Em p4, posso fazer algo assim:
$ p4 edit a.txt
$ p4 change a.txt
Change 12345 created.
Neste ponto, tenho um changlist que contém a.txt. Posso editar a descrição e continuar trabalhando sem enviar a changelist. Além disso, se descobrir que preciso fazer algumas alterações em alguns outros arquivos, como, digamos, uma correção de bug em alguma outra camada do código, posso fazer isso no mesmo cliente:
$ p4 edit z.txt
$ p4 change z.txt
Change 12346 created.
Agora eu tenho duas changelists separadas no mesmo cliente. Posso trabalhar neles ao mesmo tempo e não preciso fazer nada para "alternar" entre eles. Quando chegar a hora de se comprometer, posso enviá-los separadamente:
$ p4 submit -c 12346 # this will submit the changes to z.txt
$ p4 submit -c 12345 # this will submit the changes to a.txt
Não consigo descobrir como replicar isso no git. Pelas minhas experiências, não parece que git add
está associado ao ramo atual. Pelo que eu posso dizer, quando git commit
vou comprometer todos os arquivos que eu fiz, git add
não importa em qual branch eu estava no momento:
$ git init
Initialized empty Git repository in /home/laurence/git-playground/.git/
$ ls
a.txt w.txt z.txt
$ git add -A .
$ git commit
Initial commit.
3 files changed, 3 insertions(+), 0 deletions(-)
create mode 100644 a.txt
create mode 100644 w.txt
create mode 100644 z.txt
$ vi a.txt z.txt
2 files to edit
$ git status
# On branch master
# Changed but not updated:
# (use "git add <file>..." to update what will be committed)
# (use "git checkout -- <file>..." to discard changes in working directory)
#
# modified: a.txt
# modified: z.txt
#
no changes added to commit (use "git add" and/or "git commit -a")
$ git branch aardvark
$ git checkout aardvark
M a.txt
M z.txt
Switched to branch 'aardvark'
$ git add a.txt
$ git checkout master
M a.txt
M z.txt
Switched to branch 'master'
$ git branch zebra
$ git checkout zebra
M a.txt
M z.txt
Switched to branch 'zebra'
$ git add z.txt
$ git status
# On branch zebra
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# modified: a.txt
# modified: z.txt
#
$ git checkout aardvark
M a.txt
M z.txt
Switched to branch 'aardvark'
$ git status
# On branch aardvark
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# modified: a.txt
# modified: z.txt
Neste exemplo, os ramos aardvark e zebra parecem conter exatamente o mesmo conjunto de alterações e, com base na saída git status
, parece que fazer um commit em qualquer um deles terá o mesmo efeito. Estou fazendo algo errado?