O que fazer com o commit feito em uma cabeça desanexada


279

Usando git, fiz algo parecido com isto

git clone
git checkout {a rev number tree rev before} (here I started to be in a detached head state)
//hacking
git commit
//hacking
git commit
(some commit where made on origin/master)
git pull (which does complete because there was some error due to the fact that I'm no more on master)

Porque me disse que ainda posso confirmar quando estou em um estado de desapego, o fiz. Mas agora eu quero mesclar meu ramo principal desanexado e meu ramo principal local e, em seguida, enviar minhas alterações para origem / mestre.

Portanto, minha pergunta é como eu poderia mesclar o ramo mestre com meu estado real (cabeça desanexada)



Você poderia adicionar uma captura de tela de uma árvore de confirmação nesse estado (como uma confirmação em uma cabeça desanexada realmente se parece no gitk ou no SourceTree), que tornaria essa pergunta ainda melhor.
Florisla

Infelizmente, no momento não posso, mas se você puder continuar, ficarei feliz em vê-lo aqui. Mesmo que seja preciso um empate, ele irá torná-lo mais claro
benzeno

Respostas:


476

Crie um ramo onde você está, depois mude para mestre e mescle-o:

git branch my-temporary-work
git checkout master
git merge my-temporary-work

12
como evitar a separação de cabeças no futuro?
ycomp 4/03/16

Eu fiz isso e me encontrei à frente da origem por 5 commits. Nesse caso, você apenas faz a origem do git push?
Winnemucca

5
estranho, eu fico "Já atualizado". ao mesclar o meu trabalho temporário
Robert Sinclair

10
Não se esqueça de apagar a minha temporário ao trabalho com "git branch -d meu-temporária-obra"
Capitão Lepton

5
@ycomp "cabeça desanexada" acontece quando você edita os arquivos de uma confirmação antiga e depois confirma aqueles sem ramificação para fazer referência a essa nova confirmação posteriormente. Para evitar cabeça desanexada, não faça o checkout de confirmações antigas. Se você ainda deseja todos os arquivos a partir daí, mas como um novo commit, você pode fazer o checkout do diretório no commit, em vez do próprio commit. Veja esta resposta
lucidbrot 3/17/17

96

Você poderia fazer algo assim.

# Create temporary branch for your detached head
git branch tmp

# Go to master
git checkout master

# Merge in commits from previously detached head
git merge tmp

# Delete temporary branch
git branch -d tmp

Ainda mais simples seria

git checkout master
git merge HEAD@{1}

mas isso tem o pequeno risco de que, se você cometer um erro, pode ser um pouco mais difícil recuperar os commits feitos na cabeça desanexada.


4
Eu sei que isso é anos depois, mas obrigado por esta resposta. Não me considerei pesquisando com a resposta aceita aqui, porque não queria deixar um ramo temporário e esta resposta tem o comando de excluí-lo.
Jeremy Pridemore

8
Se você decidir usar o comando git merge HEAD@{1}você provavelmente deve garantir que é aquele que deseja usar usandogit reflog
Michael Stramel

3
Ser capaz de mesclar HEAD @ {1} salvou minha vida, pois eu já havia feito check-out antecipadamente ao mestre.
juil

estranho, eu fico "Já atualizado". ao mesclar tmp (mas os arquivos são diferentes)
Robert Sinclair

18

Isto é o que eu fiz:

Basicamente, pense no detached HEADcomo um novo ramo, sem nome. Você pode confirmar neste ramo como qualquer outro ramo. Quando terminar de enviar, você deseja enviá-lo para o controle remoto.

Portanto, a primeira coisa que você precisa fazer é dar detached HEADum nome a isso. Você pode fazê-lo facilmente, enquanto faz isso detached HEAD:

git checkout -b some-new-branch

Agora você pode enviá-lo para controle remoto como qualquer outro ramo.

No meu caso, eu também queria avançar rapidamente neste ramo para dominar junto com os commits que fiz no detached HEAD (agora some-new-branch). Tudo o que fiz foi

git checkout master

git pull # To make sure my local copy of master is up to date

git checkout some-new-branch

git merge master // This added current state of master to my changes

Claro, mesclado mais tarde master.

É sobre isso.


1
Essa resposta funcionou para mim onde os outros não. git checkout -b new-branchtrabalhou para mim. As outras sugestões pediram git branch new-branch, mas isso ainda me deixou com a cabeça desatada e o novo ramo não pegou minhas alterações.
Jesse Patel

17

Você pode simplesmente fazer git merge <commit-number>ougit cherry-pick <commit> <commit> ...

Conforme sugerido por Ryan Stewart, você também pode criar um ramo a partir do HEAD atual:

git branch brand-name

Ou apenas uma tag:

git tag tag-name

Você pode encontrar o seu número de confirmação na cabeça desanexada porgit rev-parse HEAD
KOGI

6

No caso de HEAD desanexado, as confirmações funcionam normalmente, exceto que nenhuma ramificação nomeada é atualizada. Para atualizar a ramificação principal com suas alterações confirmadas, faça uma ramificação temporária onde você está (dessa forma, a ramificação temporária terá todas as alterações confirmadas que você fez no HEAD desanexado), depois mude para a ramificação principal e mescle a ramificação temporária com O mestre.

git branch  temp
git checkout master
git merge temp

3

Um reparo fácil é apenas para criar um novo ramo para que cometem e check-out a ele: git checkout -b <branch-name> <commit-hash>.

Dessa forma, todas as alterações feitas serão salvas nesse ramo. Caso você precise limpar sua ramificação principal das sobras de confirmação, executegit reset --hard master .

Com isso, você reescreverá suas ramificações, para não incomodar ninguém com essas alterações. Verifique este artigo para obter uma melhor ilustração do estado HEAD desanexado .


1

Talvez não seja a melhor solução (reescreverá a história), mas você também pode git reset --hard <hash of detached head commit>.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.