Git: crie uma ramificação a partir de alterações não faseadas / não confirmadas no mestre


991

Contexto: estou trabalhando no master adicionando um recurso simples. Depois de alguns minutos, percebo que não era tão simples e deveria ter sido melhor trabalhar em um novo ramo.

Isso sempre acontece comigo e não tenho idéia de como alternar para outro ramo e levar todas essas alterações não confirmadas comigo, deixando o ramo mestre limpo. Eu git stash && git stash branch new_branchsimplesmente faria isso, mas é o que eu recebo:

~/test $ git status
# On branch master
nothing to commit (working directory clean)

~/test $ echo "hello!" > testing 

~/test $ 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:   testing
#
no changes added to commit (use "git add" and/or "git commit -a")

~/test $ git stash
Saved working directory and index state WIP on master: 4402b8c testing
HEAD is now at 4402b8c testing

~/test $ git status
# On branch master
nothing to commit (working directory clean)

~/test $ git stash branch new_branch
Switched to a new branch 'new_branch'
# On branch new_branch
# 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:   testing
#
no changes added to commit (use "git add" and/or "git commit -a")
Dropped refs/stash@{0} (db1b9a3391a82d86c9fdd26dab095ba9b820e35b)

~/test $ git s
# On branch new_branch
# 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:   testing
#
no changes added to commit (use "git add" and/or "git commit -a")

~/test $ git checkout master
M   testing
Switched to branch 'master'

~/test $ 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:   testing
#
no changes added to commit (use "git add" and/or "git commit -a")

Você sabe se existe alguma maneira de conseguir isso?


1
Embora exista uma solução mais simples para o seu problema, você poderia especificar em qual resultado o resultado difere do que queria?
— Gauthier

2
ao fazer o acima ou as respostas na parte inferior, as alterações não confirmadas estão no mestre e no novo ramo. Eu quero que eles apenas no novo ramo, para que eu possa fazer o checkout mestre e trabalhar em outra coisa sem que essas mudanças flutuando
— knoopx

1
veja minha resposta editada. Você precisa confirmar suas alterações locais na nova ramificação se quiser fazer checkout de um mestre limpo. Alterações locais são apenas as diferenças entre o HEAD atual e seus arquivos em disco. Essas alterações nos arquivos locais não são versionadas; você precisa dizer ao git para salvá-las em algum lugar, se quiser recuperá-las posteriormente.
— quer

Respostas:


1207

Não há necessidade de esconder.

git checkout -b new_branch_name

não toca nas alterações locais. Ele apenas cria a ramificação a partir do HEAD atual e define o HEAD lá. Então eu acho que é isso que você quer.

--- Edite para explicar o resultado do mestre de checkout ---

Você está confuso porque checkout masternão descarta suas alterações?

Como as alterações são apenas locais, o git não deseja que você as perca com muita facilidade. Ao alterar a ramificação, o git não substitui as alterações locais. O resultado do seu checkout masteré:

M   testing

, o que significa que seus arquivos de trabalho não estão limpos. O git mudou o HEAD, mas não substituiu os arquivos locais. É por isso que seu último status ainda mostra as alterações locais, embora você esteja ativo master.

Se você realmente deseja descartar as alterações locais, é necessário forçar a finalização da compra -f.

git checkout master -f

Como suas alterações nunca foram confirmadas, você as perderia.

Tente retornar ao seu ramo, confirme as alterações e faça o checkout do master novamente.

git checkout new_branch
git commit -a -m"edited"
git checkout master
git status

Você deve receber uma Mmensagem após o primeiro check-out, mas não mais após o checkout mastere não git statusdeve exibir arquivos modificados.

--- Edite para esclarecer a confusão sobre o diretório de trabalho (arquivos locais) ---

Em resposta ao seu primeiro comentário, as alterações locais são apenas ... bem, locais. O Git não os salva automaticamente, você deve pedir para salvá-los para mais tarde. Se você fizer alterações e não as confirmar ou ocultar explicitamente, o git não as fará a versão. Se você alterar HEAD ( checkout master), as alterações locais não serão substituídas desde que não sejam salvas.


32
A coisa confusa aqui é que a página de manual do git afirma que git checkout“Atualiza os arquivos na árvore de trabalho para corresponder à versão no índice ou na árvore especificada.”. Isso pressupõe que suas alterações no seu sistema de arquivos serão GONE posteriormente. Sem chance de recuperá-los. Mesmo se você disser que não, isso ainda deixa um sentimento muito ruim. Eu não confio esta em tudo . A documentação é realmente ruim ou o comportamento padrão do git é realmente perigoso. Não é necessário confiar em alguma heurística "automagica" para detectar que, nesse caso, você não deseja perder suas alterações.
— Evi1M4chine

16
Se você estiver verificando uma confirmação que substituirá as alterações locais (se o histórico entre a confirmação atual e a confirmação de destino tocar nos arquivos modificados localmente), o git se recusa. Somente se checkoutnão entrar em conflito com as alterações locais, o checkout funcionará e deixará as alterações locais em paz. No entanto, entendo o mau pressentimento, a página de manual talvez deva dizer "Atualiza arquivos não modificados na árvore de trabalho". Por outro lado, o Git não facilita demais a perda de alterações locais. git checkoutdeixa suas alterações locais em paz ou recusa se houver um conflito.
— Gauthier

1
bem, como eu faria o checkout para outro ramo sem trazer as alterações locais para lá?
— アレックス

5
@Alex git checkout <other_branch> -f. Você perderá suas alterações locais sem aviso prévio.
— Gauthier

2
@ Evi1M4chine O primeiro. A documentação está muito ruim.
— Qwertie 17/04

62

Tentar:

git stash
git checkout -b new-branch
git stash apply

6
Isso é diferente de apenas fazer 'git checkout -b new-branch' por si só?
— Adrian Mouat

Eu não acho que foi quando a resposta foi originalmente escrita, mas eu posso estar errado. Infelizmente, devido às minhas circunstâncias de trabalho, tenho usado o forforce nos últimos anos, por isso não posso atestar sua precisão agora.
— 22813 Grant Limberg

6
Ou, em vez das duas últimas etapas: git branch esconderijo novo ramo
— rethab

1
git stash de não é mais necessária
— kory

Quando você já possui uma ramificação onde deseja colocar todas as suas coisas, o stash faz sentido para mim: (Eventualmente git fetch --all; para obter a ramificação remota na origem) git stash; git checkout <existing-branch>; aplicar git stash;
— Paolof76

24

Duas coisas que você pode fazer:

git checkout -b sillyname
git commit -am "silly message"
git checkout - 

ou

git stash -u
git branch sillyname stash@{0}

( git checkout -<- o traço é um atalho para o ramo anterior em que você estava)

( git stash -u<- -usignifica que ele também leva alterações sem etapas)


7

Se você estiver usando o cliente GitHub Windows (como eu sou) e estiver em uma situação de alterações não confirmadas que deseja mover para uma nova ramificação, basta "Criar uma nova ramificação" através do cliente GitHub. Ele mudará para o ramo recém-criado e preservará suas alterações.

insira a descrição da imagem aqui


que esconde as alterações antes de criar o novo ramo para que ele não mantê-los (versão 223 no Mac OS)
— Fernando Gallego

2

Se você deseja que suas alterações não confirmadas atuais na ramificação atual sejam movidas para uma nova ramificação, use o comando a seguir para criar uma nova ramificação e copiar as alterações não confirmadas automaticamente.

git checkout -b branch_name

Isso criará um novo ramo a partir do seu ramo atual (supondo que seja mestre), copie as alterações não confirmadas e mude para o novo ramo.

Confirme suas alterações na nova ramificação.

git commit -m "First commit"

Como uma nova ramificação é criada, antes de enviá-la para remota, é necessário configurar o upstream. Use o comando abaixo para configurar o upstream e envie-o para remoto.

git push --set-upstream origin feature/feature/NEWBRANCH

Depois de pressionar este comando, um novo ramo será criado no controle remoto e seu novo ramo local será enviado para o controle remoto.

Agora, se você quiser jogar fora suas alterações não confirmadas da ramificação principal, use:

git checkout master -f

Isso descartará quaisquer alterações locais não confirmadas na finalização da compra.


Como essa resposta difere da aceita?
— kometen

Embora exista alguma sobreposição com a resposta aceita, isso fornece um guia passo a passo simples e também inclui as operações necessárias para enviar uma nova filial remotamente. Simples, claro e útil.
— Kjartan

Esta resposta é clara e me ajudou muito.
— Vadim

0

No mais recente cliente GitHub para Windows , se você tiver alterações não confirmadas, escolha criar uma nova ramificação.
Ele pergunta como lidar com esse cenário exato:

insira a descrição da imagem aqui

O mesmo se aplica se você simplesmente alternar a ramificação também.

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.