Git para usuários Perforce

86

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 :

  1. crie várias changelists pendentes em um único cliente. ( p4 change)
  2. editar uma lista de alterações pendente. (também p4 change)
  3. veja uma lista de todas as minhas changelists pendentes ( p4 changes -s pending)
  4. lista de todos os arquivos alterados em meu cliente ( p4 opened) ou em uma lista de alterações pendente ( p4 describe)
  5. veja um diff de uma changelist pendente (eu uso um script wrapper para isso que usa p4 diffe p4 describe)
  6. para um determinado arquivo, veja quais changelists enviadas afetaram quais linhas ( p4 annotate)
  7. para um determinado arquivo, veja uma lista das descrições das changelists que afetaram o arquivo ( p4 log)
  8. enviar uma changelist pendente ( p4 submit -c)
  9. 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 addestá associado ao ramo atual. Pelo que eu posso dizer, quando git commitvou comprometer todos os arquivos que eu fiz, git addnã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?

Laurence Gonsalves
fonte
2
Você pode usar o forçar para seu código pessoal, assumindo que os 5 clientes gratuitos sejam suficientes.
Logan Capaldo
3
Isso é o que eu tenho feito, mas gostaria de mudar para algo que seja de código aberto e também usado por projetos de código aberto. Tenho considerado o git e o Mercurial. Tenho me inclinado para o git porque parece ter mais ímpeto.
Laurence Gonsalves,
1
Seria melhor aprender Git do zero. O fluxo de trabalho prescrito pelo Git é muito diferente do fluxo de trabalho prescrito pelo Perforce. Os fluxos de trabalho traduzidos serão estranhos e tentar igualar os recursos confundirá sua compreensão. Felizmente, a comunidade Git oferece uma grande quantidade de documentação para iniciantes, por exemplo. git-scm.com/book
Coronel Panic
1
@ColonelPanic Eu posso ver seu ponto, mas o problema com essa documentação é que ela perde tempo explicando coisas básicas que todo usuário do Perforce já sabe. Ler essa documentação é tão chato quanto tentar ler um tutorial sobre outra linguagem de programação que gasta um capítulo explicando o que são variáveis.
Laurence Gonsalves
@ColonelPanic Dito isso, eu li alguma outra documentação do git, incluindo Git From the Bottom Up e Git for Computer Scientists que foram realmente muito úteis. Estou usando o Git há alguns anos (observe quando essa pergunta foi feita originalmente), e sinto que os principais problemas com o aprendizado do git não são a falta de documentação, mas a nomenclatura pobre, inconsistência interna, comandos muito sobrecarregados e certos peças inacabadas que não estão prontas para uso real. Eu meio que gostaria que alguém fosse limpar tudo, mas isso irritaria aqueles que se acostumaram com isso.
Laurence Gonsalves

Respostas:

72

Não usei muito forçosamente, então esta pode não ser exatamente uma tradução 1: 1. Então, novamente, sistemas de controle de fonte distribuído como git e mercurial têm um fluxo de trabalho diferente, então realmente não há (e não deveria) haver uma tradução 1: 1. Enfim, aqui vai:

  • Crie várias changelists pendentes -> Use branches ao invés. No git, os branches são leves e rápidos, levam menos de um segundo para criar e normalmente menos de dois segundos para fundir. Não tenha medo de ramificar e rebase frequentemente.

    git branch new-branch-name
    git checkout new-branch-name
    

    Ou faça tudo em uma linha:

    git checkout -b new-branch-name
    
  • Veja uma lista de todas as changelists pendentes -> Como o equivalente a várias changelists pendentes são várias ramificações, basta visualizar as ramificações:

    git branch
    

    Se você deseja visualizar filiais remotas também:

    git branch -a
    

    É considerada uma boa prática excluir imediatamente um branch após uma mesclagem bem-sucedida, para que você não precise manter o controle de qual branch está pendente para ser mesclado e quais já foram mesclados.

  • Listar todos os arquivos alterados -> Para uma única "changelist" pendente em um branch específico, o git tem um conceito de índice ou cache. Para confirmar uma mudança, você deve primeiro adicionar arquivos a este índice. Isso permite selecionar manualmente qual grupo de arquivos representa uma única alteração ou ignorar arquivos irrelevantes. Para ver o status de quais arquivos são adicionados ou não a este índice, basta fazer:

    git status
    
  • Veja uma diferença de uma lista de mudanças pendente -> Existem duas partes para isso. Primeiro, para ver uma diferença entre o diretório de trabalho e o índice:

    git diff
    

    Mas se você quiser saber a diferença entre o que você está digitando agora e o último commit, então você está realmente pedindo uma diferença entre o diretório de trabalho + índice e o HEAD:

    git diff HEAD
    
  • Para um determinado arquivo, veja quais changelists enviadas afetaram quais linhas -> Isso é fácil:

    git blame filename
    

    ou melhor ainda, se você estiver em um ambiente com janelas:

    git gui blame filename
    

    Git gui leva mais tempo para analisar o arquivo (foi escrito em tcl em vez de C), mas tem muitos recursos interessantes, incluindo a capacidade de "viajar no tempo" de volta ao passado clicando em um ID de confirmação. Eu só gostaria que eles implementassem um recurso de "viagem no tempo" para o futuro para que eu pudesse descobrir como um determinado bug será finalmente resolvido ;-)

  • Para um determinado arquivo, veja uma lista das descrições das changelists que afetaram o arquivo -> também fácil:

    git log filename
    

    Mas o git log é uma ferramenta muito mais poderosa do que apenas isso. Na verdade, a maioria dos meus scripts pessoais usa o log do git para ler o repositório. Leia a página do manual.

  • Envie uma lista de alterações pendente -> Também é fácil:

    git commit
    

Veja minha resposta a uma pergunta anterior para ver meu fluxo de trabalho típico do git: Aprendendo Git. Preciso saber se estou no caminho certo

Se você seguir o fluxo de trabalho que descrevi, verá que ferramentas como o gitk são muito mais valiosas, pois permitem ver claramente grupos de mudanças.


Resposta adicional:

Git é muito flexível e há várias maneiras de fazer o que você descreve. A coisa a lembrar é sempre iniciar um novo branch para cada recurso que você está trabalhando. Isso significa que o branch master não é tocado, então você sempre pode voltar a ele para fazer correções de bugs. Trabalhando no git, deve-se quase sempre começar com:

git checkout -b new-feature-a

Agora você pode editar o arquivo a.txt. Para trabalhar simultaneamente em outro recurso, faça:

git checkout master
git checkout -b new-feature-z

Agora você pode editar o arquivo z.txt. Para voltar a a.txt:

git checkout new-feature-a

Mas espere, há mudanças em new-feature-z e git não permitirá que você troque de branch. Neste ponto, você tem duas opções. O primeiro é o mais simples, comprometa todas as alterações no branch atual:

git add .
git commit
git checkout new-feature-a

Isso é o que eu recomendo. Mas se você realmente não está pronto para confirmar o código, pode armazená-lo temporariamente:

git stash

Agora você pode mudar para o branch new-feature-a. Para voltar ao código em que você estava trabalhando, basta abrir o estoque:

git checkout new-feature-z
git stash pop

Quando tudo estiver pronto, reúna todas as alterações no mestre:

git merge --no-ff new-feature-a
git merge --no-ff new-feature-z

Como as fusões são tão rápidas e fáceis (fáceis porque os conflitos são tão raros e a resolução de conflitos, quando uma acontece, não é muito difícil), usamos branches no git para tudo.

Aqui está outro exemplo de uso comum de branches no git que você não vê em outras ferramentas de controle de origem (exceto talvez mercurial):

Precisa ficar mudando seus arquivos de configuração para refletir seu ambiente de desenvolvimento? Então use um branch:

git checkout -b dev-config

Agora edite seus arquivos de configuração em seu editor favorito e submeta as alterações:

git add .
git commit

Agora, cada novo branch pode começar do branch dev-config em vez do master:

git checkout dev-config
git checkout -b new-feature-branch

Assim que terminar, remova as edições em dev-config de new-feature-branch usando rebase interativo:

git rebase -i master

Exclua os commits que você não deseja e salve. Agora você tem um branch limpo sem edições de configuração personalizadas. É hora de voltar ao master:

git checkout master
git merge --no-ff new-feature-branch
# because master have changed, it's a good idea to rebase dev-config:
git checkout dev-config
git rebase master

Deve-se observar que a remoção das edições com git rebase -ieven funciona quando todas as alterações acontecem no mesmo arquivo. Git se lembra das mudanças, não do conteúdo do arquivo *.

* nota: na verdade, tecnicamente não é totalmente verdade, mas como usuário é assim que parece


Mais respostas adicionais:

Portanto, a partir de seus comentários, parece que você deseja que duas ramificações existam simultaneamente para que possa testar como o código combinado funciona. Bem, esta é uma boa maneira de ilustrar o poder e a flexibilidade das ramificações.

Primeiro, uma palavra sobre a implicação de ramificações baratas e histórico modificável em seu fluxo de trabalho. Quando eu estava usando CVS e SVN, sempre fui um pouco relutante em comprometer. Isso porque comprometer código instável inevitavelmente estragaria o código de trabalho de outras pessoas. Mas com o git perdi esse medo. Isso porque no git outras pessoas não receberão minhas alterações até que eu as mescle com o master. Então agora eu me vejo comprometendo código a cada 5 linhas que escrevo. Você não precisa de uma previsão perfeita para se comprometer. Você só precisa mudar sua mentalidade: commit-to-branch == add-to-changeset, merge-to-master == commit-changeset.

Então, de volta aos exemplos. É assim que eu faria. Digamos que você tenha um branch new-feature-ze queira testá-lo new-feature-a. Gostaria apenas de criar um novo branch para testá-lo:

# assume we are currently in branch new-feature-z
# branch off this branch for testing
git checkout -b feature-z-and-feature-a
# now temporarily merge new-feature-a
git merge --no-ff new-feature-a

Agora você pode testar. Se você precisar modificar algo para fazer o recurso-z funcionar com o recurso-a, faça isso. Nesse caso, você pode mesclar novamente as alterações para o branch relevante. Use git rebase -ipara remover alterações irrelevantes da fusão.

Como alternativa, você também pode usar git rebase para alterar temporariamente a base de new-feature-z para apontar para new-feature-a:

# assume we are currently in branch new-feature-z
git rebase new-feature-a

Agora, o histórico de ramificações foi modificado para que new-feature-z seja baseado em new-feature-a em vez de master. Agora você pode testar. Quaisquer alterações confirmadas neste branch pertencerão ao branch new-feature-z. Se você precisar modificar new-feature-a, basta voltar para ele e fazer o rebase para obter as novas alterações:

git checkout new-feature-a
# edit code, add, commit etc..
git checkout new-feature-z
git rebase new-feature-a
# now new-feature-z will contain new changes from new-feature-a

Quando terminar, basta fazer o rebase de volta ao master para remover as alterações do new-feature-a:

# assume we are currently in branch new-feature-z
git rebase master

Não tenha medo de iniciar um novo ramo. Não tenha medo de iniciar um galho descartável. Não tenha medo de jogar fora galhos. E como mesclar == enviar e confirmar == add-to-changeset, não tenha medo de fazer commit com frequência. Lembre-se de que o commit é a ferramenta de desfazer definitiva do desenvolvedor.

Ah, e outra coisa, no git, branches excluídos ainda existem em seu repositório. Portanto, se você acidentalmente excluiu algo que mais tarde percebe que é útil, você sempre pode recuperá-lo pesquisando no histórico. Portanto, não tenha medo de jogar fora os galhos.

slebetman
fonte
1
Cada ramo tem seu próprio "índice" ou há um único índice compartilhado entre os ramos? Meu experimento parece sugerir o último, mas você diz "um branch específico do git tem um conceito de índice ou cache", o que sugere o primeiro.
Laurence Gonsalves,
4
É uma ferramenta diferente. Você precisa de um fluxo de trabalho diferente e, com isso, uma mentalidade e um hábito diferentes. Nenhum git não funciona da maneira que você descreve. São galhos e nada mais. Mas existem ferramentas de manipulação de ramos muito poderosas. Eu sugiro que você se considere um novato que não sabe nada sobre controle de origem e leia os tutoriais básicos. Considere sua mentalidade atual de "mau hábito", contra o qual você precisa ser reeducado no git-land. Desculpe ..
slebetman
1
Então, o que você faz no git quando tem duas coisas que deseja trabalhar simultaneamente (e no mesmo lugar, para que possa testar alterações não confirmadas uma contra a outra), mas deseja confirmá-las separadamente? Além disso, como você pode editar uma mensagem de confirmação antes de executá-la? Posso aceitar que o fluxo de trabalho é diferente, mas você não disse o que é o fluxo de trabalho equivalente a git. Dizer que esses hábitos são ruins soa muito como tentar fazer com que um bug seja um recurso.
Laurence Gonsalves,
2
Leia minha resposta atualizada. Você ainda está pensando em termos de mudanças não comprometidas quando deveria estar pensando em ramos não mesclados.
slebetman,
2
Resposta muito extensa. Em que ponto isso deve ser wikificado?
Tim Clemons,
1

Não tenho experiência suficiente em p4 para produzir uma folha de cola real, mas existem pelo menos algumas semelhanças nas quais recorrer. Um "changeset" p4 é um "commit" git.

As alterações em seu espaço de trabalho local são adicionadas ao "índice" com git add, e o índice posteriormente é confirmado com git commit. Portanto, o índice é sua lista de alterações pendente, para todos os efeitos.

Você olha as mudanças com git diffe git status, onde git diffgeralmente mostra as mudanças entre o espaço de trabalho e o índice, mas git diff --cachedmostra as mudanças entre o índice e o repositório (= sua lista de mudanças pendente).

Para obter informações mais detalhadas, recomendo http://progit.org/book/ . Já que você conhece o controle de versão em geral, você provavelmente pode folhear muito dele e extrair as informações específicas do git ...

Jakob Borg
fonte
1
Eu discordo que "um changeset p4 é um git commit"; eles são os equivalentes mais próximos, é verdade, mas um changeset p4 é muito mais próximo de um conjunto de commits git. Um changeset p4 representa um recurso, enquanto um branch git representa um recurso.
RJFalconer
@RJFalconer Erm. Um "branch" é um branch no Perforce também, não? E um "changeset" é uma coleção atômica de mudanças em um ou mais arquivos, muito parecido com um commit? Se não, o que você diria que é o equivalente p4 de commit?
Jakob Borg
Eu diria que p4 não tem equivalente, simplesmente porque o grau de atomicidade não é o mesmo; no git, posso fazer várias alterações em um determinado arquivo e depois confirmá-las em diferentes commits (git add -p), separando assim a refatoração / limpeza no histórico do recurso / correção de bug. Se eu fosse fazer isso no p4, teria que desenvolver os dois separadamente. Mesmo assim, meus commits podem não ser contínuos, já que outros desenvolvedores podem enviar entre eles (a menos que eu faça um branch privado, o que envolve duplicação freqüentemente impraticável em disco).
RJFalconer
Isenção de responsabilidade: eu só usei o p4 por alguns meses e é bem possível que haja algum recurso dele que faz isso que eu ainda não descobri.
RJFalconer
changelists p4 e branches p4 são logicamente os mesmos que git commits e git branches. p4 shelve é o equivalente a git stash. Onde eles diferem é na implementação (isto é, distribuída vs. cliente-servidor) e essa diferença resulta em p4 equivalente ao checkout git envolvendo várias etapas e tempo considerável. A sobrecarga é tal que várias ramificações são normalmente preservadas localmente no disco em vez de fazer o equivalente ao checkout git. As prateleiras p4 são armazenadas no servidor e não no repositório local.
Josh Heitzman
1

Eu sofro como você com a falta do conceito de "changelist", que não é exatamente o mesmo que git branches.

Gostaria de escrever um pequeno script que criará um arquivo de lista de mudanças com a lista de arquivos dessa lista de mudanças.

Outro comando para enviar apenas uma determinada lista de mudanças simplesmente chamando git commit -a @ change_list_contents.txt e então "git commit"

Espero que ajude Elias

Elias Bachaalany
fonte
Sim, eu realmente considerei fazer algo assim, embora na época em que fiz essa pergunta eu fosse novo no git e então queria saber a solução "nativa". Agora eu acho que a principal coisa que sinto falta é a capacidade de trabalhar em uma mensagem de commit sem realmente comprometer. Assim, poderia ser resolvido tendo um arquivo para conter a "mensagem de confirmação pendente" e talvez alguma mágica para lê-la automaticamente ao escrever uma mensagem de confirmação.
Laurence Gonsalves,
@LaurenceGonsalves, o fluxo de trabalho que eu uso é para enviar mensagens de commit imperfeitas (ou mesmo apenas "WIP") enquanto estou focado no trabalho, e depois corrigir durante meu rebase. Como os commits são puramente locais, eles não precisam ser finais até que você disponibilize seu branch (enviando-o para o remoto ou similar).
RJFalconer
1

Existe uma alternativa mais leve no git que pode fazer parte do seu fluxo de trabalho; usando a área de teste do git.

Freqüentemente, apenas faço alterações e, em seguida, envio como vários commits (por exemplo, adicionar instruções de depuração, refatorar, corrigir um bug). Em vez de configurar suas changelists forçadas, fazer alterações e enviar, você pode apenas fazer suas alterações e escolher como enviá-las (opcionalmente usando a área de teste do git).

Você pode confirmar arquivos específicos da linha de comando com:

git commit a.txt
git commit z.txt

Ou testando explicitamente os arquivos primeiro:

git add a.txt
git commit
git add z.txt
git commit

git gui permitirá que você selecione linhas ou pedaços de dentro dos arquivos para construir um commit na área de teste. Isso é muito útil se você tiver alterações em um arquivo que deseja colocar em commits diferentes. Ter mudado do git para o forçado e isso é uma coisa que eu realmente sinto falta.

Há uma pequena ressalva a ser considerada com esse fluxo de trabalho. Se você fizer alterações A e B em um arquivo, teste o arquivo e, em seguida, envie A, então você não testou esse commit (independentemente de B).

Russell Gallop
fonte
Certamente é verdade que o git permite que você faça commits ainda mais refinados do que forçosamente (ou seja: linhas e pedaços). O que eu (ainda) sinto falta do perforce é a capacidade de manter o controle da descrição da mudança (também conhecida como mensagem de confirmação) para o que estou trabalhando no momento. Por exemplo, quando vou consertar o bug # 12345, eu criaria uma lista de mudanças dizendo que estava fazendo isso (mas não enviar ou enviar). Então, enquanto trabalhava nisso, atualizava a descrição da mudança para indicar o que havia feito. Finalmente, quando terminar, enviaria a changelist.
Laurence Gonsalves
Em git, parece que o equivalente aproximado é comprometer esses pequenos bits (muitas vezes não funcionais) em um branch de desenvolvimento e, em seguida, quando tudo estiver ok, mesclar as alterações. Isso ainda parece muito mais tedioso e desajeitado para mim. Além disso, ainda não me acostumei com a ideia de comprometer código que nem mesmo compila.
Laurence Gonsalves
@LaurenceGonsalves Curioso se você já se acostumou com isso. Estou chegando ao Perforce vindo do Git e sinto falta de ser capaz de comprometer a cada 15 minutos, e então empurrar quando estiver pronto.
Damian
0

Isso não responde a sua pergunta especificamente, mas não sei se você está ciente de que uma versão 2 usuários e 5 espaços de trabalho do perforce é gratuita para baixar e usar do site do perforce .

Desta forma, você pode usar forçosamente em casa para seus projetos pessoais, se desejar. O único incômodo são os 5 espaços de trabalho que podem ser um pouco limitantes, mas é incrível ter forçosamente disponíveis para uso doméstico.

Toby Allen
fonte
2
Isso é o que eu tenho feito, mas gostaria de mudar para algo que seja de código aberto e também usado por projetos de código aberto.
Laurence Gonsalves
0

Tendo usado Perforce e git de forma bastante extensa, só há uma maneira que posso ver de chegar perto de changelists do Perforce com git.

A primeira coisa a entender é que para implementar corretamente essa funcionalidade no git de uma forma que não seja um kluge completo, por exemplo, tentar calçá-lo em branches, exigiria a seguinte mudança: git exigiria várias áreas de teste para um único branch .

As changelists do Perforce permitem um fluxo de trabalho que simplesmente não tem equivalente no git. Considere o seguinte fluxo de trabalho:

Check out a branch
Modify file A and add it to changelist 1
Modify file B and add it to changelist 2

Se você tentar fazer isso usando branches no git, você acabará com dois branches, um dos quais tem as mudanças no arquivo A, o outro tem as mudanças no arquivo B, mas nenhum lugar onde você possa ver as mudanças em ambos os arquivos Ae Bem o mesmo tempo.

A aproximação mais próxima que posso ver é usar git add . -pe, em seguida, usar o 'a'e'd' sub-comandos para selecionar ou rejeitar arquivos inteiros. No entanto, isso não é exatamente o mesmo, e a diferença aqui decorre de uma disparidade fundamental no modus operandi geral dos dois sistemas.

Git (e subversion, não que isso importe para esta discussão) permite que um arquivo seja alterado sem avisar ninguém sobre isso com antecedência. Você apenas altera um arquivo, e então deixa o git resolver tudo quando você efetua o commit das alterações. O Perforce exige que você verifique ativamente um arquivo antes que as alterações sejam permitidas, e é por esta razão que as changelists devem existir. Em essência, o Perforce requer que você adicione um arquivo ao índice antes de alterá-lo. Daí a necessidade de múltiplas changelists no Perforce, e também a razão pela qual git não tem equivalente. Simplesmente não precisa deles.

dgnuff
fonte
0

Com Git 2.27 (Q2 2020), "git p4 " aprendeu quatro novos ganchos e também " --no-verify" a opção de contorná-los (e o " p4-pre-submit" gancho existente ).

Consulte commit 1ec4a0a , commit 38ecf75 , commit cd1e0dc (14 de fevereiro de 2020) e commit 4935c45 , commit aa8b766 , commit 9f59ca4 , commit 6b602a2 (11 de fevereiro de 2020) por Ben Keene ( seraphire) .
(Fundido por Junio ​​C Hamano - gitster- no commit 5f2ec21 , 22 de abril de 2020)

git-p4: add p4 submit hooks

Assinado por: Ben Keene

O comando git "commit " suporta vários ganchos que suportam a alteração do comportamento do comando commit.

O git-p4.pyprograma possui apenas um gancho existente, " p4-pre-submit".

Este comando ocorre no início do processo.

Não há ganchos no fluxo do processo para modificar o texto da lista de alterações P4 programaticamente.

Adiciona 3 novos ganchos à git-p4.pyopção de envio.

Os novos ganchos são:

  • p4-prepare-changelist- Execute este gancho depois que o arquivo de lista de alterações for criado.
    O gancho será executado mesmo se a --prepare-p4-onlyopção for definida.
    Este gancho ignora a --no-verifyopção de manter o comportamento existente de git commit.

  • p4-changelist- Execute este gancho depois que o usuário tiver editado a lista de mudanças.
    Não execute este gancho se o usuário tiver selecionado a --prepare-p4-onlyopção.
    Este gancho honrará o --no-verify, seguindo as convenções de git commit.

  • p4-post-changelist- Execute este gancho depois que o processo de envio P4 for concluído com êxito.
    Este gancho não leva parâmetros e é executado independentemente da --no-verifyopção.

Seu valor de retorno não será verificado.

As chamadas para os novos ganchos: p4-prepare-changelist, p4-changeliste p4-post-changelisttodos devem ser chamados dentro do bloco try-finally.


Antes do Git 2.28 (Q3 2020), a --prepare-p4-onlyopção " " deveria parar após repetir um changeset, mas continuava (por engano?)

Veja o commit 2dfdd70 (12 de maio de 2020) de Ben Keene ( seraphire) .
(Fundido por Junio ​​C Hamano - gitster- no commit 7a8fec9 , 02 Jun 2020)

git-p4.py: corrigir --prepare-p4-onlyerro com vários commits

Assinado por: Ben Keene

Ao usar git p4 submitcom a --prepare-p4-onlyopção, o programa deve preparar uma única changelist p4 e notificar o usuário de que mais commits estão pendentes e então parar o processamento.

Um bug foi introduzido pelo p4-changelistrecurso de gancho que faz com que o programa continue tentando e processando todas as changelists pendentes ao mesmo tempo.

A função applyCommitretorna Truequando a aplicação do commit é bem-sucedida e o programa deve continuar.
No entanto, quando o sinalizador opcional --prepare-p4-onlyé definido, o programa deve parar após a primeira aplicação.

Altere a lógica no método de execução do P4Submit para verificar o sinalizador --prepare-p4-onlyapós concluir o applyCommitmétodo com sucesso .

Se mais de 1 confirmação estiver pendente de envio para P4, o método preparará corretamente a lista de alterações P4, no entanto, ainda sairá do aplicativo com um código de saída 1.

A documentação atual não define qual deve ser o código de saída nesta condição.

VonC
fonte