git-Kasse . entfernt keine Dateien, die nach dem Commit hinzugefügt wurden
Lesezeit: 7 Minuten
Müllhausen
Mit einem öffentlichen Repo möchte ich meinen Master-Zweig auf einen bestimmten Commit aus der Vergangenheit zurückführen. Ich habe die Optionen überprüft und das Beste für mich scheint ein einfaches Auschecken zum gewünschten Commit zu sein, dann ein Commit zum Master-Zweig. Wenn ich jedoch den Checkout durchführe, werden einige Dateien nicht entfernt, die nach dem angegebenen Commit-Hash zum Master hinzugefügt wurden.
Also zum Beispiel, wenn ich zurückkommen möchte, um mich zu verpflichten aaa1:
Aber an dieser Stelle wurden einige Dateien nachher hinzugefügt aaa1 befinden sich noch in der Arbeitskopie. Was ist der checkout Befehl, um die Arbeitskopie zu erhalten Daten zurück, wie es war aaa1?
$ git --version
git version 2.7.2.windows.1
Es kann an der Art der Kasse liegen, die ich auf stackoverflow.com/a/14460890/339874 durchgeführt habe
Als Sie verwendet haben git checkout aaa1 .du hast Git gesagt, dass es übersetzen soll aaa1 zu einem Commit, suchen Sie dieses Commit (genauer gesagt, seinen Baum) und kopieren Sie jede Datei in diesem Commit in Ihren Index / Staging-Bereich und Arbeitsbaum.
Sagen wir, nur um der Argumentation willen, dass Sie damit beginnen master enthält zwei Dateien, README und hello:
$ git checkout master
[output snipped]
$ ls
README hello
$ cat README
Yay, you read me!
$ cat hello
world
$
Sagen wir weiter, dass Commit aaa1 existiert und enthält zwei Dateien, README und addendum. Es ist README sagt Thank you for reading. Lassen Sie uns diese Kasse machen:
(Ich habe die hinzugefügt --: Es ist hier eigentlich nicht erforderlich, aber es ist eine gute Übung.) Der Inhalt von README sind die aktualisierten README. Die Datei addendum wurde ebenfalls extrahiert. Die Datei hello ist nicht entfernt und bleibt gegenüber der Version in unverändert master. Die aktualisiert README und hello werden inszeniert:
Verwenden git cleansogar mit -x, wird keine Wirkung haben: nichts muss gereinigt werden; Es gibt keine nicht bereitgestellten Dateien (hello ist inszeniert, es ist einfach nicht geändert).
Sie wollten ausdrücklich, dass der Arbeitsbaum mit dem Commit übereinstimmt aaa1, Byte für Byte. Dazu müssen Sie Dateien finden, die jetzt im Index sind, aber nicht darin waren aaa1und entfernen Sie sie.
Es gibt jedoch einen einfacheren Weg: einfach entfernen alles. Verwenden Sie dann Ihre git checkout aaa1 -- . alles herausholen aaa1. Dies füllt den Index und den Arbeitsbaum aus aaa1: Alle Dateien, die so wiederhergestellt werden müssen, wie sie vor dem Entfernen waren, werden wiederhergestellt (so, wie sie in aaa1 welches ist das gleiche so wie sie drin sind HEAD). Alle Dateien, die geändert werden müssen, damit sie mit der Art und Weise übereinstimmen, in der sie sich befanden aaa1werden wiederhergestellt (so wie sie waren aaa1 welches ist anders).
$ git rm -rf .
rm 'README'
rm 'addendum'
rm 'hello'
$ git checkout aaa1 -- .
$ git ls-files --stage
100644 ac6f2cf1acbe1b6f11c7be2288fbae72b982823c 0 README
100644 7ddf1d71e0209a8512fe4862b4689d6ff542bf99 0 addendum
$ git status --short
M README
A addendum
D hello
Sie können jetzt ein Commit durchführen und haben ein neues Commit master das, egal was vorher da war, genau den gleichen Baum hat wie aaa1.
(Ob das ein gute Idee ist eine ganz andere Sache, aber es wird Ihnen den gewünschten Zustand verschaffen.)
PraNaY
Möchten Sie Ihr Repo auf diesen Zustand zurücksetzen? Oder möchten Sie einfach, dass Ihr lokales Repo so aussieht?
Dadurch werden Ihr lokaler Code und Ihr lokaler Verlauf genauso wie bei diesem Commit. Aber wenn Sie dies jemand anderem mitteilen wollten, der die neue Historie hat, würde dies scheitern.
FALL 2: wenn Sie tun
git reset --soft [commit hash]
Dadurch werden Ihre lokalen Dateien so geändert, wie sie damals waren, aber Ihr Verlauf usw. bleibt unverändert.
Ich habe hier eine Antwort gefunden. Hier können Sie auch die zugehörige Antwort sehen.
Es ist ein öffentliches Repo, also git reset --soft ist was ich brauche 🙂
– Müllhausen
13. Mai 2016 um 5:34 Uhr
hmm git reset --soft aaa1 löscht die danach hinzugefügten Dateien nicht aaa1 entweder. Wenn ich in meine Arbeitskopie schaue, sind sie immer noch da
– Müllhausen
13. Mai 2016 um 5:46 Uhr
JA, freut mich zu wissen, dass es dir hilft.
– BETEN
13. Mai 2016 um 6:29 Uhr
Entschuldigung, das ist falsch. git reset --soft <commit-hash> tut nicht Ändern Sie die lokalen Dateien, wie in der Manpage erwähnt: --soft Does not the the index file or the working tree at all, but reset the head to <commit>
– Flimmer
31. August 2017 um 11:09 Uhr
Müllhausen
Git checkout entfernt keine Dateien, die seit einem vorherigen Commit hinzugefügt wurden. Dazu bräuchte ich git revert.
Allerdings finde ich git checkout thehash . viel einfacher zu verwenden, und es ist nicht so schwer zu sehen, welche Dateien seit diesem Hash hinzugefügt wurden:
git diff --name-status HEAD thehash
Ich habe festgestellt, dass dieser Befehl sowohl den Index als auch die Arbeitskopie auf den gewünschten Commit aktualisiert, der durch die Variable angegeben wird treeish in diesem Fall:
# use with care: destroys any uncommitted changes
git read-tree "$treeish" --reset -u
Um die Arbeitskopie zu aktualisieren, ohne den Index zu aktualisieren, könnten Sie vielleicht so etwas tun:
#!/usr/bin/env bash
set -eu
rm -rf tmp
mkdir tmp
cd tmp
git init
mkdir a
touch a/a
git add .
git commit -m a
mkdir b
touch b/b
git add .
git commit -m b
git checkout HEAD~ .
echo 'overlay'
ls -l . a b
git checkout --no-overlay HEAD~ .
echo 'no overlay'
ls -l . a b
Ergebnis:
git checkout HEAD~ .
echo 'overlay'
ls -l . a b
echo
git checkout --no-overlay HEAD~ .
echo 'no overlay'
ls -l . a b
echo
Ausgabe:
Initialized empty Git repository in /home/ciro/test/git/tmp/.git/
[master (root-commit) 216d22e] a
1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100644 a/a
[master a36e67b] b
1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100644 b/b
overlay
.:
total 2
drwxrwxr-x 2 ciro ciro 3 Jan 17 08:40 a
drwxrwxr-x 2 ciro ciro 3 Jan 17 08:40 b
a:
total 1
-rw-rw-r-- 1 ciro ciro 0 Jan 17 08:40 a
b:
total 1
-rw-rw-r-- 1 ciro ciro 0 Jan 17 08:40 b
no overlay
ls: cannot access 'b': No such file or directory
.:
total 1
drwxrwxr-x 2 ciro ciro 3 Jan 17 08:40 a
a:
total 1
-rw-rw-r-- 1 ciro ciro 0 Jan 17 08:40 a
Das sehen wir also b/b wird nur mit entfernt --no-overlay. Das Verzeichnis b wird dann auch wie üblich in git-Befehlen entfernt, weil es durch den git-Befehl leer geworden wäre.
Getestet auf Ubuntu 22.10, Git 2.37.2.
ElpieKay
git stash ist möglicherweise der schnellste Weg, um den Arbeitsbaum zu bereinigen. und dann git checkout -b $newbranch $commit-sha1-you-want um einen Zweig zu erstellen, mit dem Sie arbeiten werden. Nachdem all deine Arbeit getan ist, Git Stash-Pop um den funktionierenden Baum wiederherzustellen.
14401600cookie-checkgit-Kasse . entfernt keine Dateien, die nach dem Commit hinzugefügt wurdenyes
Es kann an der Art der Kasse liegen, die ich auf stackoverflow.com/a/14460890/339874 durchgeführt habe
– Müllhausen
13. Mai 2016 um 4:22 Uhr
Ich denke, Sie müssen es versuchen git zurücksetzen.
– BETEN
13. Mai 2016 um 5:16 Uhr
Siehe auch stackoverflow.com/questions/4114095/…
– Torek
13. Mai 2016 um 7:33 Uhr