2016-07-26 10 views
2

in git ist zu fusionieren hatte ich eine Situation wie folgt aus:Git, "move" eine genau begehen, wie es ohne Dateien

a - b - c - d - #be2c15 
        ^

Ich wollte einige Dateien aus dem Commit "a" erholen, so habe ich ein Reset SOFT ohne den Arbeitsbaum zu ändern

a - b - c - d - #be2c15 
^ 

Dann habe ich die Dateien wiederhergestellt, die als gelöscht gekennzeichnet sind.

An diesem Punkt hatte ich den Index # be2c15 zurückzusetzen und führen Sie dann aus dem Commit aber ich habe einen Fehler und verpflichtet, die Änderungen sofort wie folgt aus:

a - b - c - d - #be2c15 
\ 
    #88ae59e 

Nun ist die commit # 88ae59e enthält alle genau, dass ich will aber ist in der falschen Position. Wie kann ich es bewegen, ohne eine Datei zu berühren, die es enthält? So:

a - b - c - d - #be2c15 - #88ae59e 
+1

Ist das nicht eine Rebase? Oder vielleicht ein Cherry-Pick? – melpomene

+0

@melpomene Ein Rebase würde den Unterschied von "a" zu "# 88ae59e" auf "# be2c15" anwenden. Das ist etwas radikal anderes als ein neues Commit mit dem Parrent '# be2c15' und dem Tree von' # 88ae59e' zu ​​erstellen, was meiner Meinung nach das ist, was das OP versucht. – cmaster

Antwort

2

Ich denke, ein git rebase arbeiten könnte (aber zwischen merge Konflikten auf den Veränderungen in Abhängigkeit auftreten kann, während das Fütterungsmaterial tun).

Nach einem

$ git rebase be2c15 88ae59e 

und möglicherweise einige merge Konflikt Fixierung Sie könnte bekommen, was Sie wollten.

Verwenden git rebase --abort um wieder zurück


Aber wenn Sie einige gelöschte Dateien könnte es sein, ein einfacher Weg, dies zu tun erholen wollen.

Von der git Dokumentation über git checkout

git checkout [-p|--patch] [<tree-ish>] [--] <pathspec>…​ 

Wenn <paths> oder --patch gegeben sind, git checkout nicht Schalterzweigen. Es aktualisiert die benannten Pfade in der Arbeitsbaumstruktur von der Indexdatei oder von einem benannten <tree-ish> (meistens ein Commit). So

$ git checkout a -- path-to-folder/or/file/ 

die path-to-folder/or/file überprüfen, wie es zum Zeitpunkt der a zu begehen war.

+0

Aber der Checkout sollte auch den Index auf das designierte Commit verschieben, oder? Eigentlich denke ich, wenn es eine Möglichkeit gibt, den genauen Inhalt des Commits # 88ae59e in # be2c15 zu erhalten.

Ansonsten muss ich:
1. Kasse # 88ae59e
2. Kopieren Sie die Arbeits Baum in einem temporären Ordner unversionierte
3. Kasse # be2c15
4. Setzen Sie seine Arbeits Baum mit dem temporären Ordner
5. Commit it

Es scheint mir komisch, dass Git keinen Befehl bietet, dies automatisch zu tun – user2572526

+0

Ich hoffe, mein Edit klärt die Verwendung von 'git checkout - einige-Datei' ein bisschen besser/mehr. – AnimiVulpis

+0

Leider funktioniert es nicht, wenn der checkout Befehl ausgeführt wird in jedem Fall git macht eine Operation im Arbeitsbaum (fragt wie er mit dem Konflikt fortfahren muss) – user2572526

0

Sie, dass außerhalb von git tun kann ziemlich einfach jede Chance von Konflikten oder Irritationen zu vermeiden:

git checkout 88ae59e 
tar cf /tmp/tmp.tar --exclude=.git 
git checkout be2c15 
tar xf /tmp/tmp.tar ; rm /tmp/tmp.tar 
git add... ; git commit 
1

Unter der Annahme, dass Sie ein Commit mit dem Baum des #88ae59e, diese Befehlssequenz sollte den Trick erstellen möchten :

git checkout 88ae59e #checkout the tree that you want to commit 
#you should be in detached head state now 
git reset --soft master #switch HEAD to the intended parent commit 
#you should still be in detached head state now 
git checkout master  #reattach to your branch so it will see the following commit 
git commit ... 

Wenn Sie git reset --soft in freistehendem Kopf Zustand durchzuführen, lassen Sie den Kopf Staat werden nicht gelöst, so dass Sie Ihren Kopf auf den Zweig nach dem Reset über eine zweites git checkout Punkt benötigen.

+0

Alles funktioniert so wie ich es bis zur Kasse möchte. Es wird nicht nur die Verzweigung wieder angehängt, es wird auch versucht, die Datei im Arbeitsbaum zusammenzuführen. – user2572526

+0

Ich denke, Sie sollten überprüfen, ob Ihr 'HEAD' auf den gleichen Commit wie Ihr' Master' zeigt, indem Sie die Ausgabe von 'git show vergleichen -s HEAD' und 'git show -s master'. Diese beiden müssen identisch sein; und wenn dies der Fall ist, wird "git checkout master" augenblicklich sein und nicht fehlschlagen, da es keine Dateien berühren muss. (Der einzige und beabsichtigte Effekt des zweiten "Checkouts" ist es, vom Zustand HEAD -> be2c15' in den Zustand HEAD -> master -> be2c15' zu wechseln, so dass das folgende 'commit'' master' voranbringt und nicht nur 'HEAD'.) – cmaster