formato-patch funciona razoavelmente bem, procurando uma maneira melhor
-
13-09-2019 - |
Pergunta
Eu tenho dois ramos que são bastante diferente que rebasing parece não funcionar - ou eu não sei como fazê-lo
.Eu tenho um ramo "público" com um monte de arquivos removidos (usando filter-branch). Mesmo que a maioria dos commits igualar-se em termos de deltas, a cometer ids são todos diferentes. Eu tentei alguns métodos para puxar mudanças de meu ramo dev para meu ramo público ... acho que é difícil acreditar que ele pode fazer o que eu quero fazer - mas eu suspeito que eu só não sei como faça. Em qualquer caso, esta multa funciona, mas parece errado.
git checkout dev
git format-patch --stdout last_sync_tag > catchup.mbox
git checkout public
git am catchup.mbox
git --skip # talks about a missing file
git --skip # talks about a missing file
git --skip # talks about a missing file
Qualquer dicas ou sugestões, que provavelmente não incluem arquivos out-ramificação de filtro que você não quer no ramo público (embora, como você, em seguida, se livrar deles?), São bem-vindos.
Minha árvore (s) olhar mais ou menos assim:
dev: a-b-c-d-e-f-g-h-i-j-k
pub: t-u-v-w-x
t ? um, u ? c, v ? d, w ? E, X ? g. i, j, k são novos patches que eu gostaria de passar.
checkout pub
rebase --onto pub i # I really expected this to work
Solução
comando do Git cherry-pick
pode ser útil. Eu nunca usei isso em sua situação, mas eu acho que ele deve funcionar. A única dor é que ele não foi projetado para trabalhar em uma faixa de commits por isso, se você quiser script / automatizá-lo você tem que usar algo como git rev-list
.
Mais uma vez, eu não tentei isso, mas um script como este pode dar-lhe um bom ponto de partida
git checkout public for rev in $(git rev-list --reverse last_sync_tag..dev) ; do git cherry-pick $rev && git tag -f last_sync_tag $rev || exit 1 done
Outras dicas
Você manter regularmente os arquivos em seu ramo dev que não estão no público? Ou são apenas rondando?
Se você não tendem a fazer alterações para eles, e você está OK com reescrevendo a história um pouco, o que você poderia fazer é arranjar para tê-los criado como um único comprometer com base no seu ramo pública; e mesclagem que volta em público, mas com "nosso -s" para impedi-los realmente entrar. ( resposta anterior sobre mala git-s nosso )
Algo como:
git checkout -b dev public
git am create-dev-only-files.patch
git checkout public
git merge -s ours dev
git checkout dev
# write more dev patches...
git checkout public
git merge dev
# and this should merge in the patches without bringing in the
# dev-only files
Então, se você, em seguida, fez alterações subsequentes sobre o seu ramo dev e fundiu-los em público, se você não está mudando os arquivos que não estão no público, tudo o resto vai simplesmente aplicar. Mas se o conjunto de arquivos que você deseja suprimir sobre as mudanças públicas, isso poderia ser complicado. Você poderia tentar impedi-lo adicionando um pré-commit gancho para arquivos particulares unstage antes de iniciar qualquer cometer no ramo público, por exemplo.
Como você já usou "filter-branch" você vai ter que ajuda git encontrar o correto commit para realizar o rebase em.
Estou indo para adivinhar aqui, mas provavelmente você tem um comum 'quase' comprometer que tem duas versões, a cabeça de seu ramo público e o lugar em seu ramo dev que este cometer corresponde a (-filtrada un). Chamar a cabeça pública comprometer <PH>
eo dev cometer esse Isto corresponde a (antes da filtragem) <DevPH>
.
com o ramo dev check-out, você quer fazer algo como isto:
git rebase --onto <PH> <DevPH>
Isto diz rebase para tirar as manchas introduzidas por cada commit desde <DevPH>
no ramo atual e aplicar estes commit <PH>
. Eu acho que isso é o que você precisa.
Editar:
A sua atualização para a questão mostra que h é equivalente à cabeça do fluxo de público no ramo dev e que pretende transplante de tudo, de aqui em diante no ramo dev para o ramo público. Se assim o comando é
git rebase --onto pub h
Bem, se eu não quero um terras fileit em .gitignore. Provavelmente é a configuração não é real código para que ele não precisa de rastreamento em tudo.