2013-08-07 11 views
87

Mam 2 gałęzie Giga branch1 i branch2 i chcę scalić plik.py w branch2 do file.py w branch1 i tylko ten plik.Jak scalać określone pliki z gałęzi Git

Zasadniczo chcę po prostu pracować nad plikiem file.py w gałęzi 1, ale chcę skorzystać z polecenia scalania. Jaki jest najlepszy sposób na zrobienie tego?

+0

Możliwy duplikat [? Jak scalić selektywnych pliki z git-scalić] (http://stackoverflow.com/questions/449541/how-do-you-merge-selective-files-with- git-merge) –

+0

Możliwy duplikat [Jak scalić zmiany w jednym pliku, a raczej n łączenia commits?] (https://stackoverflow.com/questions/10784523/how-do-i-merge-changes-to-a-single-file-rather-than-merging-commits) – fbmd

Odpowiedz

99

Zaakceptowanych odpowiedź już wspomniano przy użyciu git checkout. Teraz może być treść w file.py z branch2, która nie ma już zastosowania w branch1. Taka sytuacja będzie wymagać wybrania pewnych zmian i pozostawienia innych. Dlatego, aby mieć pełną kontrolę zrobić interaktywną seryjnej za pomocą przełącznika --patch:

$ git checkout --patch branch2 file.py 

Interaktywna sekcja tryb w manualu dla git-add(1) wyjaśnia klucze, które mają być stosowane:

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 

Podział Polecenie jest szczególnie przydatne.

+1

To fajna funkcja. – rwolst

+0

To działa idealnie. Dziękujemy za dodanie tekstu pomocy w wierszu polecenia. Bez niego nie można by go użyć. – James

+1

Jak korzystać z poprawki i jednocześnie używać narzędzia do scalania? zamiast kluczowych rzeczy – Gabriel

12

Czy wszystkie modyfikacje file.py w branch2 w ich własnych zobowiązaniach, niezależnie od modyfikacji innych plików? Jeśli tak, to może po prostu cherry-pick zmiany przez:

git checkout branch1 
git cherry-pick <commit-with-changes-to-file.py> 

Inaczej merge nie działają na poszczególnych ścieżkach ... równie dobrze można po prostu stworzyć git diff skrawek file.py zmian od branch2 i git apply im branch1:

git checkout branch2 
git diff <base-commit-before-changes-to-file.py> -- file.py > my.patch 
git checkout branch1 
git apply my.patch 
80

Jak wskazano w komentarzach, technicznie rzecz biorąc nie jest to "scalenie", dlatego poniższy link wykorzystuje cytaty. Jednak rzadko potrzebuję czegoś tak skomplikowanego, jak opisują inne plakaty, więc uważam, że jest to przydatne, jeśli nie właściwe, rozwiązanie dla pytania OP.

Sprawdź tę stronę: Git Tip: How to "Merge" Specific Files from Another Branch Zapewnia najprostszy sposób, aby to zrobić, IMHO.

Zasadniczo, aby zastosować go do swojej sytuacji:

$ git checkout branch1 # i.e. make sure you're in branch1 
$ git checkout branch2 file.py 

Łatwy peasy, file.py jest teraz w branch1.

+62

Łatwo, ale to nie jest właściwie * scalenie *. To po prostu nadpisuje 'file.py' z tym, co znajduje się w gałęzi 2. –

+3

Niezwykle pomocna, gdy chcesz wczytać tylko kilka plików z funkcji na wczesnym etapie przygotowań. Potrzebowaliśmy niektórych plików z gałęzi funkcji do indeksowania niektórych danych, zanim reszta funkcji spróbuje użyć indeksowanych danych. Dzięki! –

+0

Co jeśli scalisz z powrotem plik z branch1 do branch2? Dostaniesz konflikt! – Amir

2

Aby scalić tylko zmiany z branch2's file.py, należy cofnąć pozostałe zmiany.

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 

Merge nigdy nie obejrzy żadnego innego pliku. Być może trzeba "-f" kas, jeśli drzewa są wystarczająco różne.

Zauważ, że to sprawi, że branch1 wygląda tak, jakby wszystko w historii branch2 do tego momentu zostało scalone, co może nie być tym, czego potrzebujesz. Lepsza wersja pierwszej kasie powyżej jest prawdopodobnie

git checkout -B wip `git merge-base branch1 branch2` 

w którym to przypadku popełnienia wiadomość prawdopodobnie powinien być także

git commit -m"merging only $(git rev-parse branch2):file.py into branch1" 
5

Żadna z pozostałych bieżących odpowiedzi nie spowoduje "scalenia" plików, tak jak w przypadku użycia polecenia scalania. (W najlepszym wypadku będą one wymagały ręcznego wybierania różnic.) Jeśli rzeczywiście chcesz skorzystać z łączenia za pomocą informacji od wspólnego przodka, możesz postępować zgodnie z procedurą opisaną w "Advanced Merging" section podręcznika odniesienia git.

Dla tego protokołu zakładam, że chcesz scalić plik "path/to/file.txt" z origin/master w HEAD - zmodyfikuj odpowiednio. (Nie musisz być w głównym katalogu repozytorium, ale pomaga.)

# 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 należy użyć wszystkich swoich domyślnych ustawieniach scalania do formatowania i tym podobne.

Należy również pamiętać, że jeśli „nasze” to wersja kopii roboczej, a ty nie chcesz być nadmiernie ostrożny, można pracować bezpośrednio na pliku:

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 
2

Można stash i stash pop plik, :

git checkout branch1 
git checkout branch2 file.py 
git stash 
git checkout branch1 
git stash pop 
Powiązane problemy