git merge: usuwanie plików, które chcę zachować!

Jak połączyć dwie gałęzie w git, zachowując niezbędne pliki z gałęzi?

Podczas łączenia dwóch gałęzi, jeśli plik został usunięty w jednej gałęzi, a nie w innej, plik jest ostatecznie usuwany.

Na przykład:

  • plik istnieje w master, gdy tworzysz nową gałąź
  • usuwasz Plik z master ponieważ nie potrzebujemy go (jeszcze)
  • dokonujesz zmian w gałęzi, aby dodać funkcję, , która opiera się na pliku istniejące
  • naprawiasz błędy w master (nie można go odrzucić)
  • pewnego dnia połączysz się i plik zniknie!

Jak rozmnażać:

  1. Utwórz repo git z jednym plikiem.

    git init
    echo "test" > test.txt
    git add .
    git commit -m "initial commit"
    
  2. Utwórz gałąź

    git branch branchA
    
  3. Usuń plik w master

    git rm test.txt
    git commit -m "removed file from master"
    
  4. Wprowadzić wszelkie zmiany w gałęzi, które nie dotykają usuniętego pliku (musi być niezmieniony, aby uniknąć Konflikt)

    git checkout branchA
    touch something.txt
    git add .
    git commit -m "some branch changes"
    
/ Align = "left" / plik txt został usunięty. Zakładając, że opieramy się na pliku dla branchA, jest to duży problem.

Przykłady błędów:

Merge 1

git checkout branchA
git merge master
ls test.txt

Merge 2

git checkout master
git merge branchA
ls test.txt

Rebase 1

git checkout branchA
git rebase master
ls test.txt
Author: drfloob, 2009-09-11

5 answers

To interesująca sprawa. Ponieważ usunąłeś plik po utworzeniu BranchA, a następnie połączyłeś master w BranchA, nie jestem pewien, jak Git mógłby zdać sobie sprawę, że istnieje konflikt.

Po złym połączeniu można cofnąć, a następnie ponownie połączyć, ale dodać z powrotem plik:

git checkout HEAD@{1} .
git merge --no-commit master
git checkout master test.txt
git add test.txt
git commit
 25
Author: cmcginty,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-09-11 00:40:57

Dla szybkiej poprawki w tym przypadku, "git revert" commit, który usunął plik.

Kiedy ta sytuacja pojawi się w przyszłości, lepszym sposobem na jej rozwiązanie jest upewnienie się, że utworzenie nowego pliku nastąpi w gałęzi. Następnie zostanie dodany NA master po scaleniu, ale nie masz pliku leżącego w master w międzyczasie.

 5
Author: Phil,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-09-10 21:21:12

Przykład Casey nie zadziałał w moim przypadku - nie mogłem wymeldować test.txt z master, ponieważ nie było go już w tej gałęzi:

$ git checkout master test.txt
error: pathspec 'test.txt' did not match any file(s) known to git.

Na szczęście mogłem wyciągnąć Plik z branchA's own HEAD:

$ git checkout branchA
$ git merge --no-commit master
$ git checkout HEAD test.txt
$ git add test.txt
$ git commit
 3
Author: Alex Dean,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-11-06 18:18:21

Musisz zmodyfikować plik w gałęzi, aby doszło do konfliktu scalania z delete w bagażniku.

Dokładnie to samo stanie się, jeśli na przykład usuniesz deklarację dla czegoś z pliku nagłówka w bagażniku (ponieważ nic jej nie potrzebuje)i dodasz zależność od tej deklaracji do jakiegoś pliku(plików) spoza nagłówka w gałęzi. Podczas scalania, ponieważ gałąź nie dotyka (tej części) nagłówka, usunie deklarację i wszystko będzie przerwa.

Ilekroć masz rzeczy w wielu miejscach, które są współzależne i muszą być zsynchronizowane, bardzo łatwo jest połączyć, aby po cichu wprowadzić problemy. To tylko jedna z rzeczy, o których musisz wiedzieć i sprawdzić podczas łączenia. Najlepiej jest użyć asserts w czasie kompilacji lub innych sprawdzeń czasu kompilacji, które sprawią, że wszelkie błędy będą natychmiast widoczne.

 2
Author: Chris Dodd,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-09-10 21:45:17

Moim rozwiązaniem było po prostu zmodyfikowanie plików, które musiałem zachować (dodałem komentarz, który i tak był potrzebny) i zatwierdzenie tych zmian w docelowej gałęzi, generując w ten sposób konflikt scalający, który można łatwo rozwiązać za pomocą git add i zwykłego commita.

Moja historia potoczyła się mniej więcej tak. Nazwy oddziałów zostały zmienione, aby chronić niewinnych.
  1. tworzenie i zatwierdzanie plików dla nowej funkcji master
  2. uświadom sobie, że ten dodatek będzie bardziej zaangażowany niż początkowo planowane, a więc rozgałęzione do feature_branch
  3. usunięto pliki z master, aby nie zakłócać normalnego przepływu pracy z RBs i tym podobne
  4. czas mija, więcej commitów NA master, brak na feature_branch
  5. wznowić pracę nad funkcją, {[1] } na feature_branch powoduje usunięcie oryginalnych plików (oczywiście), git reset --hard przed połączeniem
  6. zastosowano rozwiązanie opisane powyżej
 0
Author: Alex S,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-02-21 02:47:26