2013-08-18 8 views
7

Próbuję wcisnąć jakiś kod korzystając $git push origin master ale pojawia się błądJak określić, które pliki na zdalnym repozytorium uległy zmianie od czasu ostatniego pobrania git?

! [rejected]  master -> master (non-fast-forward) 
error: failed to push some refs to 'https://github.com/' 
To prevent you from losing history, non-fast-forward updates were rejected 
Merge the remote changes (e.g. 'git pull') before pushing again. See the 
'Note about fast-forwards' section of 'git push --help' for details. 

Kiedy zrobiłem $ git fetch origin master następnie $ git diff master origin/master Dostałem listę wszystkich plików i zmian, które były różne między dwoma repo. Jednak interesuje mnie tylko lista plików, które zmieniły się pomiędzy zdalnym repozytorium i ostatnim razem, gdy zrobiłem $ git pull origin master w moim lokalnym pudełku.

Czy mogę to zrobić?

Odpowiedz

2
git diff --stat master origin/master 
+0

To faktycznie porównuje twój bieżący commit ('master') przeciwko ich (' origin/master'), który nie jest * całkiem * to samo. – torek

6

git pull jest taka sama jak git fetch następnie git merge (lub git rebase).

git fetch pokazuje, w których przypadkach są aktualizowane. To pokaże coś takiego:

a8e5e4e..295bf31 master  -> origin/master 

Oznacza to ostatni raz idące głównego było w a8e5e4e teraz jest na 295bf31. Widać zmienione pliki z czymś takim:

git diff --name-status a8e5e4e..295bf31 

Ale może nawet bardziej interesujące jest wyjście gitk master...origin/master po sprowadzić. W ten sposób możesz sprawdzić zarówno zmiany po swojej stronie, jak i zmiany po stronie pochodzenia.

+0

Znalazłem, że ze względu na --name-status potrzebowałem również --name-only tylko do pokazywania nazw plików, a nie różnic. – bgoodr

4

michas' answer to odpowiednia odpowiedź na zadane pytanie.

Co zrobić, jeśli nie masz starego ref, tj. a8e5e4e części a8e5e4e..295bf31 master -> origin/master? Prawdopodobnie nie obchodzi cię to: jak zasugerował, patrząc na master...origin/master może być jeszcze ciekawiej. Ale co ta trzypunktowa składnia ... faktycznie oznacza: oznacza?

Odpowiedź jest w dokumentacji git rev-list:

Inny szczególny zapis jest <commit1>...<commit2> która jest przydatna dla scala. Wynikowy zestaw zatwierdzeń jest różnicą symetryczną między dwoma operandami. ...

Który podejrzewam, że jest dość mylące sformułowanie (a właściwie git diff używa zupełnie innego znaczenia). Ale tak naprawdę to nie jest takie skomplikowane.

Biorąc pod uwagę, że niektóre zobowiązuje można wyciągnąć tak:

master origin/master 

    E  G 
    |  | 
    D  F 
    \ /
     C 
     | 
     B 
     | 
     A 

co masz jest rozbieżność w popełnić C. Rozpocząłeś pracę, gdy master i origin/master oba wskazywały na C. Najwyraźniej popełniłeś D i E, a "oni" (kimkolwiek są) popełnili F i G. Zauważ, że przy okazji, C jest nazywana bazą scalającą podstawową.

Co oznacza master...origin/master oznacza: znajdź mi C, a następnie daj mi wszystko "stamtąd" po obu stronach. Oznacza to, że wszystkie zatwierdzenia zarówno w zatwierdzeniach, jak i w punktach, w których po raz pierwszy spotykają się.

Jeśli prowadzisz gitk master...origin/master zobaczysz tylko, że: wszystkie commity ty wykonane i wszystkie commity one wykonane. Ale jeśli uruchomisz git diff flags master...origin/master, git diff wyrzuci większość tego. Zamiast tego znajduje bazę scalającą C, i porównuje ją z nazwą po prawej stronie.

Zakładając, że jesteś w swoim oddziale master (tj. HEAD po prostu oznacza "master"), możesz to skrócić jeszcze bardziej. Aby zobaczyć jakie pliki zostały zmodyfikowane od Państwa i ich oddziały rozeszły, wystarczy uruchomić:

$ git diff --stat ...origin/master # or --name-status, etc 

Pozostawienie imienia oznacza HEAD, więc to jest taka sama jak HEAD...origin/master która jest taka sama jak master...origin/master.

Jeśli git jest na tyle nowy, @{u} odnosi się do „prądowym w górę gałąź” (czyli od master znajdziesz origin/master), dzięki czemu można uruchomić:

$ git diff --stat '[email protected]{u}' 

(cytaty są w celu ochrony szelki z muszli, mogą one być lub nie muszą być potrzebne w twojej powłoce). Działa to nawet jeśli jesteś na develop z origin/develop jak jego upstream lub featureX z origin/featureX jak jego prąd itp


Jeśli nie masz gitk, spróbuj:

$ git log --graph --boundary ...origin/master 

(lub '[email protected]{u}' jak wspomniano powyżej). Potrzebujesz --boundary, aby dołączyć zatwierdzenie scalenia. Możesz również dodać --oneline --decorate.

Właściwie gitk pokaże scalającej też, podobnie jak komendy w przypisie 1. Oznacza to, że wykorzystuje --boundary zawierać punkt spotkań zobowiązuje (to nie jest to samo, jako zasady łączenia, ale blisko dość).

Zakłada się, że istnieje dokładnie jedno zatwierdzenie bazy scalającej. W tych przypadkach powinno to być prawdą. Tak więc git diff porównuje drzewo dla C z drzewem dla G na początku gałęzi upstream. Porównujesz "gdzie oni byli" z "gdzie skończyli", niezależnie od punktów pośrednich, które odwiedzili, być może na arbitralnie długiej trasie. :-) Na przykład, jeśli commit F dodaje plik this/that, a następnie zatwierdza G usuwa go ponownie, nie zobaczysz pliku.

Powiązane problemy