Slechts één bestand opbergen van meerdere bestanden die zijn gewijzigd met Git?

Hoe kan ik slechts één van meerdere gewijzigde bestanden op mijn branch opslaan?


Antwoord 1, autoriteit 100%

git stash push -p -m "my commit message"

-plaat je de hunks selecteren die moeten worden opgeslagen; hele bestanden kunnen ook worden geselecteerd.

Je wordt gevraagd om een paar acties voor elke hunk:

  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

Antwoord 2, autoriteit 43%

Disclaimer: het volgende antwoord is voor git vóór git 2.13. Voor git 2.13 en hoger, bekijk een ander antwoord verderop.


Waarschuwing

Zoals vermeld in de opmerkingen, plaatst dit alles in de stash, zowel gefaseerd als niet-gefaseerd. De –keep-index laat de index gewoon met rust nadat de stash is voltooid. Dit kan samenvoegconflicten veroorzaken wanneer je later de voorraad opent.


Hiermee wordt alles opgeslagen dat u niet eerder hebt toegevoegd. Gewoon git addde dingen die je wilt behouden, en voer het dan uit.

git stash --keep-index

Als je bijvoorbeeld een oude commit in meer dan één wijzigingenset wilt splitsen, kun je deze procedure gebruiken:

  1. git rebase -i <last good commit>
  2. Markeer enkele wijzigingen als edit.
  3. git reset HEAD^
  4. git add <files you want to keep in this change>
  5. git stash --keep-index
  6. Repareer dingen waar nodig. Vergeet niet om git addwijzigingen door te voeren.
  7. git commit
  8. git stash pop
  9. Herhaal indien nodig vanaf #5.
  10. git rebase --continue

Antwoord 3, autoriteit 24%

Sinds Git 2.13 (Q2 2017), kun je individuele bestanden opslaan met git stash push:

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

Wanneer pathspecwordt gegeven aan ‘git stash push‘, registreert de nieuwe stash alleen de gewijzigde statussen voor de bestanden die overeenkomen met de pathspec
Zie “Wijzigingen in specifieke bestanden opslaan” voor meer informatie.

Vereenvoudigd voorbeeld:

git stash push path/to/file

De testcasevoor deze functie laat nog een paar opties zien:

test_expect_success 'stash with multiple pathspec arguments' '
    >foo &&
    >bar &&
    >extra &&
    git add foo bar extra &&
    git stash push -- foo bar &&   
    test_path_is_missing bar &&
    test_path_is_missing foo &&
    test_path_is_file extra &&
    git stash pop &&
    test_path_is_file foo &&
    test_path_is_file bar &&
    test_path_is_file extra

Het originele antwoord (hieronder, juni 2010) ging over handmatig te selecteren wat u wilt stakken.

CaseBash Opmerkingen:

Dit (de stash --patchoriginele oplossing) is leuk, maar vaak heb ik veel bestanden aangepast, dus het gebruik van patch is irritant

Bukzor Antwoord (upvoted, november 2011) suggereert een meer praktische oplossing, op basis van
git add+ git stash --keep-index.
Ga zien en zijn antwoord opvolgen, wat de officiële (in plaats van van mij) zou moeten zijn.

Over die optie, chhh wijst op een alternatieve workflow in de opmerkingen:

U moet “git reset --soft” na zo’n stash om uw duidelijke enscenering terug te krijgen:
Om bij de oorspronkelijke staat te komen – een duidelijk staginggebied en met slechts enkele selecteer niet-geënsceneerde modificaties, kan men de index zachtjes opnieuw instellen (zonder iets zoals u te plegen – Bukzor – deed).


(origineel antwoord juni 2010: handmatige stash)

Nog, git stash save --patchZou u in staat stellen om de gedeeltelijke stashing te bereiken die u zoekt:

Met --patch, kunt u in interactief hunks selecteren in de diff tussen het hoofd en de werkboom die moet worden gepersteld.
Het stash-item is zo geconstrueerd dat de indexstatus hetzelfde is als de indexstatus van uw repository, en de werkboom bevat alleen de wijzigingen die u interactief hebt geselecteerd. De geselecteerde wijzigingen worden vervolgens teruggedraaid vanuit uw werkboom.

Dat zal echter de volledige index opslaan (wat misschien niet is wat je wilt omdat het andere bestanden kan bevatten die al zijn geïndexeerd), en een gedeeltelijke werkboom (die eruit zou kunnen zien als degene die je wilt opslaan).

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

is misschien beter geschikt.


Als --patchniet werkt, kan een handmatig proces:

Voor een of meerdere bestanden zou een tussenoplossing zijn om:

  • kopieer ze buiten de Git-repo
    (Eigenlijk stelt eleotlecrameen voor interessant alternatief)
  • git stash
  • kopieer ze terug
  • git stash# deze keer worden alleen de bestanden die je wilt opslaan
  • git stash pop stash@{1}# pas al uw bestandswijzigingen opnieuw toe
  • git checkout -- afile# reset het bestand naar de HEAD-inhoud, vóór lokale wijzigingen

Aan het einde van dat nogal omslachtige proces, heb je maar één of meerdere bestanden opgeslagen.


Antwoord 4, autoriteit 3%

Gebruik git stash push, als volgt:

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

Bijvoorbeeld:

git stash push -- my/file.sh

Dit is beschikbaar sinds Git 2.13, uitgebracht in het voorjaar van 2017.


Antwoord 5, autoriteit 3%

Als git stash -p(of git add -pmet stash --keep-index) te omslachtig zou zijn, vond ik het is gemakkelijker om diff, checkouten applyte gebruiken:

Alleen een bepaald bestand/map “stashen”:

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

En daarna

git apply stashed.diff

Antwoord 6, autoriteit 2%

Stel dat je 3 bestanden hebt

a.rb
b.rb
c.rb

en je wilt alleen b.rb en c.rb opslaan, maar niet a.rb

je kunt zoiets als dit doen

# 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

En je bent klaar!
HTH.


Antwoord 7

Als u geen bericht wilt opgeven met uw opgeslagen wijzigingen, geeft u de bestandsnaam door na een dubbel streepje.

$ git stash -- filename.ext

Als het een niet-getrackt/nieuw bestand is, moet je het eerst stagen.

Deze methode werkt in git-versies 2.13+


Antwoord 8

Een andere manier om dit te doen:

# 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">

Ik kwam hierheen nadat ik (nogmaals) naar deze pagina kwam en vond de eerste twee antwoorden niet leuk (het eerste antwoord beantwoordt gewoon niet de vraag en ik heb het niet leuk om met de -pinteractieve modus).

Het idee is hetzelfde als wat @vonc heeft voorgesteld om bestanden buiten de repository te gebruiken, u opslaat de gewenste wijzigingen die u ergens wilt, verwijder de wijzigingen die u niet in uw stash wilt, en vervolgens opnieuw de wijzigingen aanbrengen en vervolgens opnieuw aanbrengen de weg. Ik heb echter de git-stash gebruikt als de “ergens” (en als gevolg daarvan is er een extra stap aan het einde: het verwijderen van de cahnges die je in de voorraad hebt gestopt, omdat je deze ook uit de weg hebt verplaatst).


Antwoord 9

Update (2/14/2015) – Ik heb het script een beetje herschreven, om het geval van conflicten beter te verwerken, die nu moeten worden gepresenteerd als ongehinderde conflicten in plaats van .REJ-bestanden.


Ik vind het vaak intuïtiever om de inferen van @ Bukzor’s aanpak te doen. Dat wil zeggen, om enkele wijzigingen aan te brengen en vervolgens alleen die geënsceneerde veranderingen te steken.

Helaas biedt Git geen git-stash –only-index of vergelijkbaar, dus ik maakte een script op om dit te doen.

#!/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

U kunt het bovenstaande script opslaan als git-stash-indexergens op uw pad en kan het dan oproepen als Git Stash-index

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

Nu de stash bevat een nieuw vermelding dat alleen de wijzigingen bevat die u had geënsceneerd en uw werkboom nog steeds geen niet-gestudeerde wijzigingen bevat.

In sommige gevallen kunnen de werkboomwijziging afhangen van de indexwijzigingen, dus wanneer u de indexwijzigingen versterkt, hebben de werkboom veranderingen een conflict. In dit geval krijgt u de gebruikelijke ongehinderde conflicten die u kunt oplossen met Git Merge / Git Mergetool / enz.


Antwoord 10

U kunt dit eenvoudig doen:

git stash push "filename"

of met een optioneel bericht

git stash push -m "Some message" "filename"

Antwoord 11

Omdat het creëren van filialen in Git triviaal is, kunt u gewoon een tijdelijke branch maken en de afzonderlijke bestanden erin controleren.


Antwoord 12

Als u slechts enkele van gewijzigde bestanden wilt stakken, voegt u gewoon gewoon andere bestanden toe in de Stage , en vervolgens uitvoeren git stash push --keep-index

Het zal alle niet-gestakte gewijzigde bestanden stakken


Antwoord 13

Sla de volgende code op in een bestand, bijvoorbeeld met de naam stash. Gebruik is stash <filename_regex>. Het argument is de reguliere expressie voor het volledige pad van het bestand. Bijvoorbeeld, om a/b/c.txt, stash a/b/c.txtof stash .*/c.txt, etc.

$ chmod +x stash
$ stash .*.xml
$ stash xyz.xml

Code om naar het bestand te kopiëren:

#! /usr/bin/expect --
log_user 0
set filename_regexp [lindex $argv 0]
spawn git stash -p
for {} 1 {} {
  expect {
    -re "diff --git a/($filename_regexp) " {
      set filename $expect_out(1,string)
    }
    "diff --git a/" {
      set filename ""
    }
    "Stash this hunk " {
      if {$filename == ""} {
        send "n\n"
      } else {
        send "a\n"
        send_user "$filename\n"
      }
    }
    "Stash deletion " {
      send "n\n"
    }
    eof {
      exit
    }
  }
}

Antwoord 14

Voor het geval je eigenlijk bedoelt dat je wijzigingen weggooittelkens wanneer je git stashgebruikt (en git stash niet echt gebruikt om het tijdelijk op te bergen), in dat geval kun je gebruik

git checkout -- <file>

[OPMERKING]

Die git stashis gewoon een sneller en eenvoudiger alternatief voor vertakking en dingen doen.


Antwoord 15

Het probleem met VonC’s `tussenoplossing’ voor het kopiëren van bestanden naar buiten de Git-repo is dat je padinformatie verliest, wat het later een beetje lastig maakt om een heleboel bestanden terug te kopiëren.

Een vind het makkelijker om tar te gebruiken (vergelijkbare tools zullen dat waarschijnlijk doen) in plaats van kopiëren:

  • tar cvf /tmp/stash.tar pad/naar/sommige/bestandspad/naar/sommige/andere/bestand (… etc.)
  • git afrekenpad/naar/sommige/bestandspad/naar/sommige/andere/bestand
  • git stash
  • tar xvf /tmp/stash.tar
  • enz. (zie VonC’s `tussentijdse’ suggestie)

Antwoord 16

Soms heb ik een niet-gerelateerde wijziging in mijn branch gemaakt voordat ik het heb gecommit, en ik wil het naar een andere branch verplaatsen en het apart vastleggen (zoals master). Ik doe dit:

git stash
git checkout master
git stash pop
git add <files that you want to commit>
git commit -m 'Minor feature'
git stash
git checkout topic1
git stash pop
...<resume work>...

Let op de eerste stash& stash popkan worden geëlimineerd, je kunt al je wijzigingen meenemen naar de masterbranch wanneer je afrekent, maar alleen als er geen conflicten zijn. Ook als je een nieuwe branch aanmaakt voor de gedeeltelijke wijzigingen, heb je de stash nodig.

Je kunt het vereenvoudigen, ervan uitgaande dat er geen conflicten en geen nieuwe branch zijn:

git checkout master
git add <files that you want to commit>
git commit -m 'Minor feature'
git checkout topic1
...<resume work>...

Stash niet eens nodig…


Antwoord 17

Dit kan eenvoudig in 3 stappen met SourceTree.

  1. Maak tijdelijk alles vast wat je niet wilt bewaren.
  2. Git voeg al het andere toe en berg het dan op.
  3. Plaats je tijdelijke commit door git reset uit te voeren, waarbij je de commit target voor je tijdelijke.

Dit kan allemaal binnen enkele seconden in Sourcetree worden gedaan, waar u gewoon op de bestanden (of zelfs individuele regels) kunt klikken die u wilt toevoegen. Eenmaal toegevoegd, plegen ze gewoon aan een tijdelijke commit. Klik vervolgens op het selectievakje om alle wijzigingen toe te voegen en klik vervolgens op Stash om alles te steken. Met de gegestoorde veranderingen uit de weg staan, kijk dan naar uw Plaats-lijst en noteer de hash voor de commit vóór uw tijdelijke commit en voer vervolgens ‘Git Reset Hash_B4_temp_Commit’ uit, wat in feite is als “Popping” de commit door uw tak in de Geef vlak voor hem. Nu, je bent achtergelaten met alleen de dingen die je niet wilde.


Antwoord 18

Ik zou gebruiken git stash save --patch. Ik vind de interactiviteit niet irritant omdat er opties zijn om de gewenste bewerking op volledige bestanden toe te passen.


Antwoord 19

Elk antwoord hier is zo gecompliceerd …

Hoe zit het met dit om “stash”:

git diff /dir/to/file/file_to_stash > /tmp/stash.patch
git checkout -- /dir/to/file/file_to_stash

Dit om het bestandswijziging terug te vullen:

git apply /tmp/stash.patch

Exact hetzelfde gedrag als het stassen van een bestand en er weer in kloppen.


Antwoord 20

Ik heb hiervoor antwoorden en opmerkingen beoordeeld en een aantal vergelijkbare draden. Houd er rekening mee dat geen van de volgende opdrachten correct is voor het in staat zijn om eventuele specifieke gevolgde / ongeschaalde bestanden te stakken

  • git stash -p (--patch): Selecteer Hunks handmatig, exclusief niet-gesraceerde bestanden
  • git stash -k (--keep-index): Stash Alle Tracked / Untracked-bestanden en bewaar ze in de werkdirectory
  • git stash -u (--include-untracked): Stash Alle Tracked / Untracked-bestanden
  • git stash -p (--patch) -u (--include-untracked): Ongeldige opdracht

Momenteel is de meest redelijke methode om elke specifieke gevolgde / niet-gesraceerde bestanden te kunnen stakken, is:

  • Begin tijdelijk de bestanden die u niet wilt stash
  • toevoegen en stash
  • POP de tijdelijke commit

Ik schreef een eenvoudig script voor deze procedure in een antwoord op een andere vraag , en Er zijn stappen voor het uitvoeren van de procedure in Sourcetree hier .


Antwoord 21

Oplossing

Lokale wijzigingen:

  • file_a (gewijzigd) niet geënsceneerd
  • FILE_B (gewijzigd) Niet geënsceneerd
  • FILE_C (gewijzigd) Niet geënsceneerd

Om een ​​stash “my_stash” te maken met alleen de wijzigingen op file_c :

1. git add file_C
2. git stash save --keep-index temp_stash
3. git stash save my_stash
4. git stash pop stash@#{1}

Gereed.


Uitleg

  1. voeg file_c toe aan het staginggebied
  2. Maak een tijdelijke stash met de naam “Temp_Stash” en bewaar de wijzigingen op file_c
  3. Maak de gewenste stash (“My_Stash”) met alleen de wijzigingen op File_C
  4. Pas de wijzigingen in “TEMP_STASH” (FILE_A EN FILE_B) op uw lokale code en verwijder de stash

U kunt GIT-status gebruiken tussen de stappen om te zien wat er aan de hand is.


Antwoord 22

Wanneer u probeert te schakelen tussen twee takken, vindt deze situatie plaats.

Probeer de bestanden toe te voegen met “git add filepath” toe.

Voer later deze regel uit

git stash --keep-index


Antwoord 23

Als u een enkel bestand wilt instellen git stash --patch [file].

Dit wordt gevraagd: Stash this hunk [y,n,q,a,d,j,J,g,/,e,?]? ?. Typ gewoon a(stop deze hunk en alle latere hunks in het bestand) en je bent in orde.


Antwoord 24

Vergelijkbare situatie. Heb gepleegd en besefte dat het niet oké is.

git commit -a -m "message"
git log -p

Op basis van de antwoorden heeft dit me geholpen.

# revert to previous state, keeping the files changed
git reset HEAD~
#make sure it's ok
git diff
git status
#revert the file we don't want to be within the commit
git checkout specs/nagios/nagios.spec
#make sure it's ok
git status
git diff
#now go ahead with commit
git commit -a -m "same|new message"
#eventually push tu remote
git push

Antwoord 25

In deze situatie git add -p(interactief), git commit -m blahen bewaar wat er over is indien nodig.


Antwoord 26

Ik weet niet hoe ik het op de opdrachtregel moet doen, ik gebruik alleen SourceTree. Stel dat u bestand A hebt gewijzigd en twee wijzigingshunks in bestand B hebt. Als u alleen de tweede hunk in bestand B wilt opslaan en al het andere onaangeroerd wilt laten, doet u dit:

  1. Alles in scene zetten
  2. Voer wijzigingen aan uw werkkopie uit die alle wijzigingen in bestand A ongedaan maken (bijv. start externe diff-tool en zorg dat bestanden overeenkomen.)
  3. Laat bestand B eruit zien alsof er slechts een tweede wijziging op is toegepast. (bijv. externe diff-tool starten en eerste wijziging ongedaan maken.)
  4. Maak een stash met “Gefaseerde wijzigingen behouden”.
  5. Maak alles ongedaan
  6. Klaar!

Antwoord 27

git add .                           //stage all the files
git reset <pathToFileWillBeStashed> //unstage file which will be stashed
git stash                           //stash the file(s)
git reset .                         // unstage all staged files
git stash pop                       // unstash file(s)

Antwoord 28

voor gebruikers van vs-code. De knop Stash voor de Wijzigingen Group in de git-zijbalkweergave zal alleen de bestanden in de groep worden versteld. Dus als u een aantal bestanden uit die groep verplaatst, kunt u de resterende bestanden vervolgens opstellen. De enige manier waarop ik weet om wat bestanden weg te bewegen zonder de wijzigingen aan te brengen, is om ze te posten. Dus:

  1. Stage de bestanden die u niet wilt stash
  2. Klik op de knop Stash in de Wijzigingen Groepskop
  3. UnSploegen de bestanden die u uit de manier hebt verhuisd

Antwoord 29

Een ingewikkelde manier zou zijn om alles te plegen:

git add -u
git commit // creates commit with sha-1 A

Resetten terug naar de oorspronkelijke commit, maar uitchecken the_one_file van de nieuwe commit:

git reset --hard HEAD^
git checkout A path/to/the_one_file

Nu kunt u de_one_file stash:

git stash

opruimen door de toegewijde inhoud in uw bestandssysteem op te slaan tijdens het opnieuw instellen van de oorspronkelijke commit:

git reset --hard A
git reset --soft HEAD^

Ja, enigszins ongemakkelijk …


ANTWOORD 30

Ik vond geen antwoord om te zijn wat ik nodig had en dat is net zo eenvoudig als:

git add -A
git reset HEAD fileThatYouWantToStash
git commit -m "committing all but one file"
git stash

Dit stitst precies één bestand.

Other episodes