Git rozwiązuje konflikt za pomocą --ours / - ich dla wszystkich plików

113

Czy istnieje sposób rozwiązania konfliktu dla wszystkich plików przy użyciu wyewidencjonowania --oursi --theirs? Wiem, że możesz to zrobić dla pojedynczych plików, ale nie mogłeś znaleźć sposobu, aby zrobić to dla wszystkich.

exe163
źródło
7
Działa git checkout --ours -- .? Te .środki w bieżącym katalogu, gdy stosowana od korzenia katalogu roboczego, więc to w zasadzie oznacza całą katalogu roboczego. Nie jestem pewien, czy to zadziała z --oursflagą i nie jestem pewien, jak poradzi sobie z konfliktami usuniętych lub zmienionych nazw plików.
@Cupcake Użyłem go pomyślnie. Może to powinna być odpowiedź?
Pedro Gimeno

Odpowiedzi:

90

Po prostu przejrzyj katalog roboczy i wyślij dane wyjściowe za pomocą polecenia xargs:

grep -lr '<<<<<<<' . | xargs git checkout --ours

lub

grep -lr '<<<<<<<' . | xargs git checkout --theirs

Jak to działa: grepprzeszuka każdy plik w bieżącym katalogu (the .) i podkatalogach rekurencyjnie ( -rflaga), szukając znaczników konfliktu (ciąg '<<<<<<<')

-llub --files-with-matchesflagi powoduje grep do wyjścia tylko nazwę pliku, gdzie łańcuch został znaleziony. Skanowanie zatrzymuje się po pierwszym dopasowaniu, więc każdy dopasowany plik jest wyprowadzany tylko raz.

Dopasowane nazwy plików są następnie przesyłane potokiem do xargs , narzędzia, które dzieli potokowany strumień wejściowy na indywidualne argumenty dla git checkout --ourslub--theirs

Więcej pod tym linkiem .

Ponieważ wpisywanie tego za każdym razem w wierszu poleceń byłoby bardzo niewygodne, jeśli często go używasz, utworzenie aliasu dla wybranej powłoki może nie być złym pomysłem : Bash jest zwykle używany .

Ta metoda powinna działać przez co najmniej Git w wersji 2.4.x.

Dmitri
źródło
14
Myślę, że zamiast grepowania można też użyć git diff --name-only --diff-filter=U.
tajski
10
Również git status | grep both | awk '{print $3}' | xargs git checkout --[theirs|ours]. Szybsze niż grepowanie, jeśli masz duży projekt.
joshbodily
1
@joshbodily Nice. Nie mam projektów tak dużych, żebym zauważył różnicę, ale widzę, że byłoby to znacznie szybsze zwłaszcza, gdyby zmieniło się kilka plików w porównaniu z całkowitą liczbą w katalogu ---- co powinno mieć miejsce w przypadku normalnego zatwierdza.
Dmitri,
1
Zauważ, że to nie działa w przypadku konfliktów zmiany nazwy / zmiany nazwy, np.CONFLICT (rename/rename): Rename "a.txt"->"c.txt" in branch "HEAD" rename "a.txt"->"b.txt" in "master"
Borek Bernard
1
Jeszcze inna opcja: git status --porcelain | egrep '^UU' | cut -d ' ' -f 2 |xargs git checkout --[theirs|ours].
Zitrax
52

Można -Xoursalbo -Xtheirsz git mergetak dobrze. Więc:

  1. przerwać bieżące scalanie (na przykład za pomocą git reset --hard HEAD)
  2. połącz, używając preferowanej strategii ( git merge -Xourslub git merge -Xtheirs)

OŚWIADCZENIE: oczywiście można wybrać tylko jedną opcję, albo -Xoursalbo -Xtheirs, czy użyć innej strategii należy oczywiście pójść plik po pliku.

Nie wiem, czy jest na to sposób checkout, ale szczerze nie sądzę, że jest to strasznie przydatne: wybór strategii poleceniem checkout jest przydatny, jeśli chcesz różnych rozwiązań dla różnych plików, w przeciwnym razie po prostu wybierz podejście strategii scalania.

ThanksForAllTheFish
źródło
Dzięki, nie wiedziałem, że mają „- swoje” i „- ich” do połączenia. Wydaje się, że w przypadku scalania w rzeczywistości nie są one częścią strategii „-s”, ale częścią opcji rekurencyjnych „-X”. Nasza wersja „-s” w rzeczywistości zastępuje wszystkie pliki bez scalania, a ich nie istnieje.
exe163
Nie ma opcji --theirslub --ours-Option do git v1.9.4. Byłoby podejście git merge -s recursive -Xtheirs BRANCH.
fbmd
--theirsi --oursnie są dostępne ani z git 2.2.0. Albo moja odpowiedź nie była precyzyjna, albo były dostępne w starszej wersji gita (ta odpowiedź jest dość stara w epoce IT). Właściwe podejście to -X. Aktualizuję odpowiednio
ThanksForAllTheFish
Od wersji 2.4.0 - nasze i - ich są nadal bardzo dostępne git-scm.com/docs/git-checkout
Dmitri.
Próbowałem tego i otrzymałem komunikat „automatyczne scalanie nie powiodło się, napraw konflikty”. To polecenie najwyraźniej nie działa zgodnie z przeznaczeniem i zalecam jego unikanie - zbyt błędne.
Adam
37

git checkout --[ours/theirs] .zrobisz, co zechcesz, o ile jesteś u źródła wszystkich konfliktów. nasze / ich dotyczą tylko niescalonych plików, więc nie powinieneś specjalnie wyszukiwać konfliktów grep / find / etc.

Cory Petosky
źródło
5
Dla mnie to nie wydaje się powracać do podkatalogów.
Daniel Baughman
5
Rozumiem error: path 'foo/bar/blah' does not have our version.
Robin Green
Używam gita w wersji 2.16.2.windows.1 i u mnie działa idealnie. Dzięki!
Pankwood
30
git diff --name-only --diff-filter=U | xargs git checkout --theirs

Wydaje się, że wykonuje swoją pracę. Zauważ, że aby to osiągnąć, musisz przejść do katalogu głównego repozytorium git.

Piotr
źródło
3
Myślę, że jest to lepsza odpowiedź niż ta z największą liczbą głosów, ponieważ (1) dotyczy wszystkich plików, a nie tylko katalogu roboczego; i (2) nie będzie miał żadnych kruchości przy szukaniu znaczników konfliktu. Polecenie „git diff” wyświetla tutaj wszystkie niescalone ścieżki, czyli dokładnie to, co chcemy sprawdzić.
bchurchill
Miły! Zawsze martwiłem się o wiarygodność znaczników konfliktu grep
00-BBB
2
function gitcheckoutall() {
    git diff --name-only --diff-filter=U | sed 's/^/"/;s/$/"/' | xargs git checkout --$1
}

Dodałem tę funkcję w pliku .zshrc .

Używaj ich w ten sposób: gitcheckoutall theirslubgitcheckoutall ours

iWheelBuy
źródło