Hier ist ein Beispiel:
>git status
# On branch master
nothing to commit (working directory clean)
>git checkout -b test-branch
>vi test.c
>git add test.c
>git commit -m "modified test.c"
>vi README
>git add README
>git commit -m "modified README"
Jetzt möchte ich ein ' git rebase -i
' machen, mit dem ich alle Commits für diesen Zweig neu festlegen kann. Gibt es so etwas wie ' git rebase -i HEAD~MASTER
' oder ähnliches? Ich denke, ich könnte es tun git rebase -i HEAD~2
, aber ich möchte wirklich nicht zählen müssen, wie viele Commits gemacht wurden. Ich könnte es auch tun, git rebase -i sha1
aber ich möchte das Git-Protokoll nicht durchkämmen, um das erste Commit sha1 zu finden. Irgendwelche Ideen?
master
oder nur die Commits bearbeiten, die Sie gerade vorgenommen habentest-branch
?Antworten:
Haben Sie versucht :
git rebase -i master
?quelle
git rebase -i master
ist, dass Sie möglicherweise Zusammenführungskonflikte haben, mit denen Sie sich im Moment nicht unbedingt befassen möchten, oder dass Sie einen Konflikt in einem Commit beheben, um ihn im Verlauf des Rebases erneut in einem anderen Commit zu beheben. Ich habe eine Antwort hinzugefügt, die eine Alternative dazu bietet, und eine Alternative zur Angabe des genauen Commits oder der Anzahl der Commits, von denen Sie zurückgreifen möchten.rerere
ist dein Freund, wann immer du umbasierst.git rebase master
(nicht-i
nur für Tests) , und es führt bereits zu Konflikten.Ok, ich gehe davon aus, dass der Zweig "Feature" heißt und von "Master" verzweigt wurde.
Es gibt diesen kleinen Git-Befehl namens Merge-Base. Es dauert zwei Commits und gibt Ihnen den ersten gemeinsamen Vorfahren von beiden. Damit...
... gibt Ihnen den ersten gemeinsamen Vorfahren dieser beiden Commits. Ratet mal, was passiert, wenn Sie dieses Commit für git rebase -i bestehen, wie ...
Interaktive Rebase vom ersten gemeinsamen Vorfahren von Master und Feature-Zweig. Profitieren! ;)
quelle
git merge-base master HEAD
was immer für den aktuellen Zweig funktionieren sollte, ohne den aktuellen Zweignamen einzugeben. Alias dieser Befehl und Sie haben Ihren netten kurzen Git-Befehl.git rebase -i $(git merge-base @{u} HEAD)
- Dies setzt voraus, dass Ihr aktueller Zweig so eingestellt ist, dass er den Basiszweig verfolgt. Beispiel:git branch feature1 origin/master
würde Herkunft / Master verfolgen. Jetzt müssen Sie das nicht einmal mehr eingeben.Das Problem bei allen bereitgestellten Lösungen ist, dass Sie nicht vom ersten Commit an neu starten können. Wenn der erste Commit-Hash XYZ ist und Sie Folgendes tun:
Sie werden erst ab dem 2. Commit neu gestartet.
Wenn Sie vom ersten Commit zurücksetzen möchten, gehen Sie wie folgt vor:
quelle
Verwenden Sie gitk (* nix) oder gitx (OS X) oder ähnliches auf anderen Plattformen und sehen Sie sich an, welches Commit das Stammverzeichnis Ihres Zweigs war. Dann renne:
Zum Beispiel habe ich ein Repository, das ich mit gitx überprüft habe:
Jetzt, wo ich den Root-Hash kenne, kann ich Folgendes ausführen:
Und mein Editor erscheint damit und ich kann / squash / was auch immer nach Belieben neu anordnen.
Ich bin mir sicher, dass es eine magische Möglichkeit gibt, Git davon zu überzeugen, die Wurzel des Baumes automatisch herauszufinden, aber ich weiß nicht, was es ist.
EDIT: Diese Magie ist dies:
Dadurch werden alle Commits in diesem Zweig angezeigt, und durch Weiterleiten an cat wird der Pager deaktiviert, sodass das erste Commit sofort angezeigt wird.
EDIT: Die Kombination der oben genannten ergibt eine vollautomatische Lösung:
quelle
| cat
scheint wie eine nutzlose Verwendung von Katze, wenn Sie verwenden könnengit --no-pager
.Das Problem beim Rebasieren aus einem anderen Zweig
Das Problem dabei
git rebase -i master
ist, dass Sie möglicherweise Zusammenführungskonflikte haben, mit denen Sie sich im Moment nicht unbedingt befassen möchten, oder dass Sie einen Konflikt in einem Commit beheben, um ihn im Verlauf des Rebases erneut in einem anderen Commit zu beheben.Das Problem beim erneuten Basieren von einem bekannten Commit
Das ganze Problem hierbei ist, dass Sie wissen müssen, auf welches Commit Sie sich beziehen müssen, entweder durch seine SHA oder HEAD ~ x usw. Dies ist nur ein kleiner Ärger, aber es ist ein Ärger.
Der bessere Weg
Wenn Sie stattdessen alle Commits in Ihrem aktuellen Zweig neu festlegen möchten, können Sie .gitconfig den folgenden Alias hinzufügen, da der letzte Commit für den übergeordneten Zweig freigegeben wurde:
Verwendung
Wie es funktioniert
Dieser Alias ist nur ein Shell-Skript, das ein Argument verwendet, das auf den übergeordneten Zweig verweist. Dieses Argument wird übergeben
git merge-base
, um das letzte gemeinsame Commit zwischen diesem Zweig und dem aktuellen Zweig zu bestimmen.quelle
master
zum Zeitpunkttest-branch
der Erstellung sein (sagen wir3hgn45
). Diese Rebase macht also eigentlich nichts. Es heißt, diesen Zweig von (aber nicht einschließlich)3hgn45
nach (und einschließlich)HEAD
auf neu zu gründen3hgn45
. Aber vielleichtmaster
(dh nicht wirklich neu basiert, da Sie dieselbe Basis beibehalten und nur einige Commits für den aktuellen Zweig bearbeiten).master
, sondern einfach alle Commits zu einem zusammenfassen, da sie davon abweichenmaster
.rbca = "!git rebase $(git merge-base HEAD \"$1\") ${@:2} #"
Seit Git v1.7.10 können Sie nur
git rebase
ohne Argument ausführen , und es wird den Verzweigungspunkt finden und Ihre lokalen Änderungen im Upstream-Zweig neu begründen.Sie müssen den Upstream-Zweig konfiguriert haben, damit dies funktioniert (dh
git pull
ohne Argument sollte funktionieren).Weitere Informationen finden Sie in den Dokumenten zur Git-Rebase :
quelle
Eine allgemeine Lösung (wenn Sie den Namen des Upstream-Zweigs nicht kennen) lautet:
Beachten Sie, dass Sie neue Commits aus dem Upstream abrufen, wenn Ihr Upstream (wahrscheinlich ein Tracking-Zweig) seit Ihrer letzten Neugründung aktualisiert wurde. Wenn Sie keine neuen Commits einfügen möchten, verwenden Sie
aber das ist ein bisschen mundvoll.
quelle
Interaktives Rebase ausgehend vom einzelnen Zusammenführungspunkt von HEAD und seinem Upstream, einschließlich aller Commits in HEAD, die sich nicht in seinem Upstream befinden.
Mit anderen Worten genau das, was Sie wollen.
quelle
@{u}
konfiguriert, dann können Sie argumentless verwendengit rebase
, siehe meine Antwort.