Frage Verstecke nur eine Datei aus mehreren Dateien, die sich mit Git geändert haben?


Wie kann ich nur eine von mehreren geänderten Dateien in meiner Filiale speichern?


2437
2018-06-14 20:52


Ursprung


Antworten:


Warnung

Wie in den Kommentaren angemerkt, bringt dies alles ins Spiel, sowohl inszeniert als auch nicht inszeniert. Der --keep-Index hinterlässt nur den Index nach dem Stash. Dies kann zu Mischkonflikten führen, wenn Sie den Stash später freigeben.


Dies wird alles verstauen, was Sie noch nicht hinzugefügt haben. Gerade git add die Dinge, die du behalten willst, dann führe es aus.

git stash --keep-index

Wenn Sie beispielsweise eine alte Festschreibung in mehr als eine Änderungsmenge aufteilen möchten, können Sie folgendermaßen vorgehen:

  1. git rebase -i <last good commit>
  2. Markieren Sie einige Änderungen als edit.
  3. git reset HEAD^
  4. git add <files you want to keep in this change>
  5. git stash --keep-index
  6. Repariere die Dinge wie nötig. Vergiss nicht zu git add irgendwelche Veränderungen.
  7. git commit
  8. git stash pop
  9. Wiederholen Sie den Vorgang nach Bedarf von Punkt 5.
  10. git rebase --continue

1216
2017-11-30 21:28



Sie können auch verwenden git stash save -p "my commit message". Auf diese Weise können Sie auswählen, welche Hunks zum Stash hinzugefügt werden sollen, ganze Dateien können ebenfalls ausgewählt werden.

Sie werden mit ein paar Aktionen für jedes Stück aufgefordert:

   y - stash this hunk
   n - do not stash this hunk
   q - quit; do not stash this hunk or any of the remaining ones
   a - stash this hunk and all later hunks in the file
   d - do not stash this hunk or any of the later hunks in the file
   g - select a hunk to go to
   / - search for a hunk matching the given regex
   j - leave this hunk undecided, see next undecided hunk
   J - leave this hunk undecided, see next hunk
   k - leave this hunk undecided, see previous undecided hunk
   K - leave this hunk undecided, see previous hunk
   s - split the current hunk into smaller hunks
   e - manually edit the current hunk
   ? - print help

2612
2017-07-31 11:59



Seit git geht es grundsätzlich um die Verwaltung eines gesamten Repositories Inhalt und index (und nicht eine oder mehrere Dateien), git stash Angebote, nicht überraschend, mit dem gesamten Arbeitsverzeichnis.

Seit Git 2.13 (Q2 2017) können Sie einzelne Dateien speichern mit:

git stash push [--] [<pathspec>...]

Sehen "Stash ändert sich in bestimmte Dateien" für mehr.


In der ursprünglichen Antwort (unten, Juni 2010) ging es darum, manuell auszuwählen, was Sie speichern möchten.

Casebash Bemerkungen:

Dies (die stash --patch Original-Lösung) ist nett, aber oft habe ich viele Dateien geändert, so dass die Verwendung von Patch nervt

Bukzorist es Antworten (upvoted, November 2011) schlägt eine praktikablere Lösung vor, basierend auf
git add + git stash --keep-index.
Geh und überhöre seine Antwort, die die offizielle sein sollte (statt meiner).

Über diese Option chhh weist auf einen alternativen Workflow in den Kommentaren hin:

Du solltest "git reset --soft"Nach so einem Vorrat, um Ihre klare Inszenierung zurück zu bekommen:
  Um in den ursprünglichen Zustand zu gelangen - welcher ein klarer Staging-Bereich ist und nur einige wenige unzensierte Modifikationen enthält, könnte man den Index sanft zurücksetzen, um zu erhalten (ohne etwas wie Sie zu begehen - bukzor - tat).


(Originalantwort Juni 2010: Handbuch Stash)

Noch, git stash save --patch könnte es Ihnen ermöglichen, das partielle Versteck zu erreichen, nach dem Sie suchen:

Mit --patchSie können interaktiv Hunks aus dem Diff zwischen HEAD und dem zu speichernden Arbeitsbaum auswählen.
  Der Stash-Eintrag ist so aufgebaut, dass sein Index-Status dem Index-Status Ihres Repositorys entspricht und sein Arbeitsbaum nur die Änderungen enthält, die Sie interaktiv ausgewählt haben. Die ausgewählten Änderungen werden dann von Ihrem Arbeitsbaum zurückgesetzt.

Das wird jedoch den vollständigen Index speichern (was möglicherweise nicht das ist, was Sie wollen, da er möglicherweise bereits indizierte Dateien enthält) und einen Teilarbeitsbaum (der so aussehen könnte wie der, den Sie speichern möchten).

git stash --patch --no-keep-index

könnte besser passen.


Ob --patchfunktioniert nicht, könnte ein manueller Prozess:

Für eine oder mehrere Dateien wäre eine Zwischenlösung:

  • kopiere sie außerhalb des Git Repo
    (Tatsächlich, eleotlecram schlägt vor interessante Alternative)
  • git stash
  • kopiere sie zurück
  • git stash # Dieses Mal werden nur die gewünschten Dateien gespeichert
  • git stash pop stash@{1} # Übernehmen Sie alle Ihre Dateiänderungen erneut
  • git checkout -- afile # Setzen Sie die Datei vor allen lokalen Änderungen auf den HEAD-Inhalt zurück

Am Ende dieses ziemlich umständlichen Prozesses wirst du nur eine oder mehrere Dateien versteckt haben.


237
2018-06-14 21:23



Wann git stash -p (oder git add -p mit stash --keep-index) wäre zu umständlich, ich fand es einfacher zu benutzen diff, checkout und apply:

Um nur eine bestimmte Datei / Verzeichnis zu "stash":

git diff path/to/dir > stashed.diff
git checkout path/to/dir

Dann danach

git apply stashed.diff

76
2018-02-12 13:44



Nehmen wir an, Sie haben 3 Dateien

a.rb
b.rb
c.rb

und du willst nur b.rb und c.rb speichern, aber nicht a.rb

Sie können so etwas tun

# commit the files temporarily you don't want to stash
git add a.rb
git commit -m "temp" 

# then stash the other files
git stash save "stash message"

# then undo the previous temp commit
git reset --soft HEAD^
git reset

Und du bist fertig! HTH.


43
2017-10-31 07:10



Benutzen git stash push, so was:

git stash push [--] [<pathspec>...]

Beispielsweise:

git stash push -- my/file.sh

Dies ist verfügbar seit Git 2.13, veröffentlicht im Frühjahr 2017.


33
2017-08-15 13:10



Eine andere Möglichkeit, dies zu tun:

# Save everything
git stash 

# Re-apply everything, but keep the stash
git stash apply

git checkout <"files you don't want in your stash">

# Save only the things you wanted saved
git stash

# Re-apply the original state and drop it from your stash
git stash apply stash@{1}
git stash drop stash@{1}

git checkout <"files you put in your stash">

Ich kam dazu, nachdem ich (wieder einmal) auf diese Seite kam und die ersten zwei Antworten nicht mochte (die erste Antwort beantwortet die Frage einfach nicht und ich mochte es nicht, mit der -p interaktiver Modus).

Die Idee ist dieselbe wie die von @VonC vorgeschlagene Verwendung von Dateien außerhalb des Repositorys. Sie speichern die gewünschten Änderungen irgendwo, entfernen die Änderungen, die Sie nicht möchten, und übernehmen dann die Änderungen, die Sie aus dem Weg geschafft haben. Allerdings habe ich den Git Stash als "irgendwo" benutzt (und als Ergebnis gibt es einen zusätzlichen Schritt am Ende: Entfernen der Veränderungen, die du in den Vorrat gelegt hast, weil du diese auch aus dem Weg geschafft hast).


25
2018-02-05 10:16



Update (2/14/2015) - Ich habe das Skript ein wenig umgeschrieben, um Konflikte besser zu lösen, die jetzt als nicht verschachtelte Konflikte statt als .rej-Dateien dargestellt werden sollten.


Ich finde es oft intuitiver, das Gegenteil von @ Bukzors Ansatz zu tun. Das heißt, einige Änderungen vorzunehmen und dann nur diese gestaffelten Änderungen zu speichern.

Leider bietet Git keinen Git-Stash -only-Index oder ähnliches, also habe ich ein Skript dafür ausgetüftelt.

#!/bin/sh

# first, go to the root of the git repo
cd `git rev-parse --show-toplevel`

# create a commit with only the stuff in staging
INDEXTREE=`git write-tree`
INDEXCOMMIT=`echo "" | git commit-tree $INDEXTREE -p HEAD`

# create a child commit with the changes in the working tree
git add -A
WORKINGTREE=`git write-tree`
WORKINGCOMMIT=`echo "" | git commit-tree $WORKINGTREE -p $INDEXCOMMIT`

# get back to a clean state with no changes, staged or otherwise
git reset -q --hard

# Cherry-pick the index changes back to the index, and stash.
# This cherry-pick is guaranteed to succeed
git cherry-pick -n $INDEXCOMMIT
git stash

# Now cherry-pick the working tree changes. This cherry-pick may fail
# due to conflicts
git cherry-pick -n $WORKINGCOMMIT

CONFLICTS=`git ls-files -u`
if test -z "$CONFLICTS"; then
    # If there are no conflicts, it's safe to reset, so that
    # any previously unstaged changes remain unstaged
    #
    # However, if there are conflicts, then we don't want to reset the files
    # and lose the merge/conflict info.
    git reset -q
fi

Sie können das obige Skript als speichern git-stash-index irgendwo auf Ihrem Pfad, und kann es dann als Git-Stash-Index aufrufen

# <hack hack hack>
git add <files that you want to stash>
git stash-index

Jetzt enthält der Stash einen neuen Eintrag, der nur die Änderungen enthält, die Sie bereitgestellt haben, und Ihr funktionierender Baum enthält noch nicht gestartete Änderungen.

In einigen Fällen hängen die Änderungen der Arbeitsbaumstruktur von den Indexänderungen ab. Wenn Sie die Indexänderungen verwerfen, haben die Änderungen der Arbeitsbaumstruktur einen Konflikt. In diesem Fall erhalten Sie die üblichen nicht zusammengelaufenen Konflikte, die Sie mit git merge / git mergetool / etc auflösen können.


22
2018-06-16 21:00