Ho 2 rami git branch1 e branch2 e voglio unire file.py in branch2 in file.py in branch1 e solo quel file.
In sostanza, voglio solo lavorare su file.py in branch1 ma voglio sfruttare il comando merge. Qual è il modo migliore per farlo?
Ho 2 rami git branch1 e branch2 e voglio unire file.py in branch2 in file.py in branch1 e solo quel file.
In sostanza, voglio solo lavorare su file.py in branch1 ma voglio sfruttare il comando merge. Qual è il modo migliore per farlo?
Risposte:
Quando il contenuto provienefile.py
da branch2 che non si applica più a branch1 , è necessario selezionare alcune modifiche e lasciarne altre. Per un controllo completo, esegui un'unione interattiva usando l' --patch
opzione:
$ git checkout --patch branch2 file.py
La sezione della modalità interattiva nella pagina man di git-add(1)
spiega i tasti che devono essere usati:
y - stage this hunk
n - do not stage this hunk
q - quit; do not stage this hunk nor any of the remaining ones
a - stage this hunk and all later hunks in the file
d - do not stage this hunk nor any of the later hunks in the file
g - select a hunk to go to
/ - search for a hunk matching the given regex
j - leave this hunk undecided, see next undecided hunk
J - leave this hunk undecided, see next hunk
k - leave this hunk undecided, see previous undecided hunk
K - leave this hunk undecided, see previous hunk
s - split the current hunk into smaller hunks
e - manually edit the current hunk
? - print help
Il comando split è particolarmente utile.
git init <dir>
) e infine eliminarlo ( rm -r <dir>
).
Sebbene non sia un'unione di per sé, a volte è necessario l'intero contenuto di un altro file su un altro ramo. Il post sul blog di Jason Rudolph fornisce un modo semplice per copiare i file da un ramo all'altro. Applicare la tecnica come segue:
$ git checkout branch1 # ensure in branch1 is checked out and active
$ git checkout branch2 file.py
Ora file.py
è ora in branch1 .
file.py
con qualsiasi cosa sia nel ramo 2.
Nessuna delle altre risposte correnti "unirà" i file, come se si stesse utilizzando il comando unisci. (Nella migliore delle ipotesi, ti verrà richiesto di selezionare manualmente le differenze.) Se effettivamente vuoi trarre vantaggio dall'unione usando le informazioni di un antenato comune, puoi seguire una procedura basata su quella che si trova nella sezione "Unione avanzata" di git Manuale di riferimento.
Per questo protocollo, suppongo che tu voglia unire il file 'path / to / file.txt' da origin / master a HEAD - modificalo come appropriato. (Non devi essere nella directory principale del tuo repository, ma aiuta.)
# Find the merge base SHA1 (the common ancestor) for the two commits:
git merge-base HEAD origin/master
# Get the contents of the files at each stage
git show <merge-base SHA1>:path/to/file.txt > ./file.common.txt
git show HEAD:path/to/file.txt > ./file.ours.txt
git show origin/master:path/to/file.txt > ./file.theirs.txt
# You can pre-edit any of the files (e.g. run a formatter on it), if you want.
# Merge the files
git merge-file -p ./file.ours.txt ./file.common.txt ./file.theirs.txt > ./file.merged.txt
# Resolve merge conflicts in ./file.merged.txt
# Copy the merged version to the destination
# Clean up the intermediate files
git merge-file dovrebbe usare tutte le impostazioni di unione predefinite per la formattazione e simili.
Si noti inoltre che se la "nostra" è la versione della copia funzionante e non si desidera essere eccessivamente cauti, è possibile operare direttamente sul file:
git merge-base HEAD origin/master
git show <merge-base SHA1>:path/to/file.txt > ./file.common.txt
git show origin/master:path/to/file.txt > ./file.theirs.txt
git merge-file path/to/file.txt ./file.common.txt ./file.theirs.txt
Tutte le modifiche sono file.py
in branch2
proprio commit, separate dalle modifiche ad altri file? In tal caso, puoi semplicemente cherry-pick
modificare le modifiche:
git checkout branch1
git cherry-pick <commit-with-changes-to-file.py>
Altrimenti, merge
non funziona su singoli percorsi ... potresti anche creare una git diff
patch di file.py
modifiche da branch2
e git apply
loro a branch1
:
git checkout branch2
git diff <base-commit-before-changes-to-file.py> -- file.py > my.patch
git checkout branch1
git apply my.patch
Puoi stash
e stash pop
il file:
git checkout branch1
git checkout branch2 file.py
git stash
git checkout branch1
git stash pop
Per unire solo le modifiche da branch2 file.py
, fai scomparire le altre modifiche.
git checkout -B wip branch2
git read-tree branch1
git checkout branch2 file.py
git commit -m'merging only file.py history from branch2 into branch1'
git checkout branch1
git merge wip
L'unione non guarderà nemmeno nessun altro file. Potrebbe essere necessario '-f' i checkout se gli alberi sono abbastanza diversi.
Nota che questo lascerà branch1 come se tutto nella storia di branch2 a quel punto fosse stato unito, che potrebbe non essere quello che vuoi. Una versione migliore del primo checkout sopra è probabilmente
git checkout -B wip `git merge-base branch1 branch2`
nel qual caso probabilmente dovrebbe essere anche il messaggio di commit
git commit -m"merging only $(git rev-parse branch2):file.py into branch1"
Sono nella stessa situazione, voglio unire un file da un ramo che ha molti commit su di esso su 2 rami. Ho provato molti modi sopra e altri che ho trovato su Internet e tutti hanno fallito (perché la cronologia del commit è complessa), quindi decido di fare la mia strada (la strada folle).
git merge <other-branch>
cp file-to-merge file-to-merge.example
git reset --hard HEAD (or HEAD^1 if no conflicts happen)
cp file-to-merge.example file-to-merge
Quello che ho fatto è un po 'manuale, ma io:
revert
;HEAD~1
, ovvero il loro stato nel commit di unione;Brutta? Sì. Facile da ricordare? Anche si.