Hoe een stash een naam geven en op naam ophalen in git?

Ik had altijd de indruk dat je een stash een naam kon geven door git stash save stashnamete doen, wat je later zou kunnen toepassen door git stash apply stashnamete doen. . Maar het lijkt erop dat in dit geval alleen stashnamewordt gebruikt als stashbeschrijving.

Is er geen manier om een stash een naam te geven? Zo niet, wat zou u aanbevelen om gelijkwaardige functionaliteit te bereiken? In wezen heb ik een kleine voorraad die ik periodiek zou willen toepassen, maar ik wil niet altijd in git stash listmoeten zoeken wat het werkelijke stashnummer is.


Antwoord 1, autoriteit 100%

Zo doe je het:

git stash push -m "my_stash"

Waar "my_stash"de naam van de stash is.

Nog meer nuttige dingen om te weten: alle stashes worden in een stapel opgeslagen.
Typ:

git stash list

Hiermee worden al je stashes weergegeven.

Om een stash toe te passen en uit de stash-stack te verwijderen, typt u:

git stash pop stash@{n}

Om een stash toe te passen en in de stash-stack te houden, typt u:

git stash apply stash@{n}

Waar nde index is van de opgeslagen wijziging.

Merk op dat u een stash kunt toepassen en in de stapel kunt houden door de stashnaam te gebruiken:

git stash apply my_stash_name

Antwoord 2, autoriteit 47%

git stash saveis verouderdvanaf 2.15.x/2.16, in plaats daarvan kun je git stash push -m "message"

Je kunt het als volgt gebruiken:

git stash push -m "message"

waarbij “bericht” uw notitie voor die voorraad is.

Om de stash op te halen kun je gebruik maken van: git stash list. Dit zal een lijst als deze weergeven, bijvoorbeeld:

stash@{0}: On develop: perf-spike
stash@{1}: On develop: node v10

Dan gebruik je gewoon applyen geef je het de stash@{index}:

git stash apply stash@{1}

Referenties
git stash man-pagina


Antwoord 3, autoriteit 14%

Als je gewoon op zoek bent naar een lichtgewicht manier om sommige of al je huidige werkkopiewijzigingen op te slaan en ze later naar believen opnieuw toe te passen, overweeg dan een patchbestand:

# save your working copy changes
git diff > some.patch
# re-apply it later
git apply some.patch

Af en toe vraag ik me af of ik hiervoor stashes moet gebruiken en dan zie ik dingen als de waanzin hierboven en ben ik tevreden met wat ik doe 🙂


Antwoord 4, autoriteit 10%

Je kunt van een stash een branch maken als je denkt dat het belangrijk genoeg is:

git stash branch <branchname> [<stash>]

van de man-pagina:

Hiermee wordt een nieuwe branch gemaakt en uitgecheckt met de naam <branchname>, beginnend bij de commit waarop de <stash>oorspronkelijk is gemaakt, worden de wijzigingen toegepast die zijn vastgelegd in <stash>naar de nieuwe werkboom en index, en laat de <stash>vallen als dat met succes is voltooid. Als er geen <stash>is opgegeven, wordt de laatste toegepast.

Dit is handig als de branch waarop je git stash savehebt uitgevoerd voldoende is veranderd zodat git stash apply mislukt vanwege conflicten. Aangezien de stash wordt toegepast bovenop de commit die HEAD was op het moment dat git stash werd uitgevoerd, herstelt het de oorspronkelijke stash-status zonder conflicten.

Je kunt deze nieuwe vertakking later rebasen naar een andere plaats die afstamt van waar je was toen je opsloeg.


Antwoord 5, autoriteit 4%

Stashes zijn niet bedoeld als permanente dingen zoals jij dat wilt. Je zou waarschijnlijk beter geholpen zijn met het gebruik van tags op commits. Construeer het ding dat je wilt opbergen. Maak er een commitment van. Maak een tag voor die commit. Rol dan je branch terug naar HEAD^. Als je die stash nu opnieuw wilt toepassen, kun je git cherry-pick -n tagnamegebruiken (-nis --no-commit).


Antwoord 6, autoriteit 4%

gebruik git stash push -m aNameForYourStashom het op te slaan. Gebruik vervolgens git stash listom de index van de stashte leren die je wilt toepassen. Gebruik dan git stash pop --index 0om de stash te popen en toe te passen.

opmerking: ik gebruik git versie 2.21.0.windows.1


Antwoord 7, autoriteit 4%

Ik heb deze twee functies in mijn .zshrc-bestand:

function gitstash() {
    git stash push -m "zsh_stash_name_$1"
}
function gitstashapply() {
    git stash apply $(git stash list | grep "zsh_stash_name_$1" | cut -d: -f1)
}

Ze op deze manier gebruiken:

gitstash nice
gitstashapply nice

Antwoord 8, autoriteit 4%

Dus ik weet niet zeker waarom er zoveel consternatie is over dit onderwerp. Ik kan noem een git stashmet zowel een pushals de verouderde save, en ik kan een regex gebruiken om het terug te trekken met een apply:

Git stash methode om een naam toe te passen

$ git stash push -m "john-hancock"
$ git stash apply stash^{/john-hancock}

Zoals eerder vermeld, is de opdracht saveverouderd, maar het werkt nog steeds, dus je kunt dit gebruiken op oudere systemen waar je ze niet kunt bijwerken met een pushbellen. In tegenstelling tot de opdracht pushis de schakeloptie -mniet vereist bij save.

// save is deprecated but still functional  
$ git stash save john-hancock

Dit is Git 2.2 en Windows 10.

Visueel bewijs

Hier is een prachtige geanimeerde GIF die het proces laat zien.

Geanimeerde GIF met een git-stash van toepassing met een identificeerbare naam.

Opeenvolging van gebeurtenissen

De GIF werkt snel, maar als je kijkt, is het proces dit:

  1. Het lscommando toont 4 bestanden in de directory
  2. touch example.htmlvoegt een 5e bestand toe
  3. git stash push -m "john-hancock" -a(De -abevat niet-getrackte bestanden)
  4. De opdracht lstoont 4 bestanden na de stash, wat betekent dat de stash en de impliciete harde reset werkten
  5. git stash apply stash^{/john-hancock}loopt
  6. Het lscommando geeft 5 bestanden weer, waaruit blijkt dat het example.htmlbestand is teruggebracht, wat betekent dat het git stash applycommando werkte.

Heeft dit zin?

Om eerlijk te zijn, weet ik niet zeker wat het voordeel van deze aanpak is. Het heeft waarde om de stash een naam te geven, maar niet het ophalen. Misschien om de shelve and unshelveproces zou handig zijn, maar het is nog steeds veel gemakkelijker om een stash gewoon op naam te zetten.

$ git stash pop 3
$ git stash apply 3

Dat lijkt me veel makkelijker dan de regex.


Antwoord 9, autoriteit 2%

Hoe zit het hiermee?

git stash save stashname
git stash apply stash^{/stashname}

Antwoord 10

Alias

sapply = "!f() { git stash apply \"$(git stash list | awk -F: --posix -vpat=\"$*\" \"$ 0 ~ pat {print $ 1; exit}\")\"; }; f"

Gebruik

git sapply "<regex>"

  • compatibel met Git voor Windows

Bewerken: ik bleef bij mijn oorspronkelijke oplossing, maar ik begrijp waarom de meerderheid de voorkeur geeft aan de versie van Etan Reisner (hierboven). Dus even voor de goede orde:

sapply = "!f() { git stash apply \"$(git stash list | grep -E \"$*\" | awk \"{ print $ 1; }\" | sed -n \"s/://;1p\")\"; }; f"

Antwoord 11

Het is jammer dat git stash apply stash^{/<regex>}niet werkt (het doorzoekt niet echt de stashlijst, zie de opmerkingen onder de antwoord geaccepteerd).

Hier zijn drop-in vervangingen die git stash listdoorzoeken op regex om de eerste (meest recente) stash@{<n>}te vinden en die vervolgens door te geven naar git stash <command>:

# standalone (replace <stash_name> with your regex)
(n=$(git stash list --max-count=1 --grep=<stash_name> | cut -f1 -d":") ; if [[ -n "$n" ]] ; then git stash show "$n" ; else echo "Error: No stash matches" ; return 1 ; fi)
(n=$(git stash list --max-count=1 --grep=<stash_name> | cut -f1 -d":") ; if [[ -n "$n" ]] ; then git stash apply "$n" ; else echo "Error: No stash matches" ; return 1 ; fi)
# ~/.gitconfig
[alias]
  sshow = "!f() { n=$(git stash list --max-count=1 --grep=$1 | cut -f1 -d":") ; if [[ -n "$n" ]] ; then git stash show "$n" ; else echo "Error: No stash matches $1" ; return 1 ; fi }; f"
  sapply = "!f() { n=$(git stash list --max-count=1 --grep=$1 | cut -f1 -d":") ; if [[ -n "$n" ]] ; then git stash apply "$n" ; else echo "Error: No stash matches $1" ; return 1 ; fi }; f"
# usage:
$ git sshow my_stash
 myfile.txt | 1 +
 1 file changed, 1 insertion(+)
$ git sapply my_stash
On branch master
Your branch is up to date with 'origin/master'.
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)
    modified:   myfile.txt
no changes added to commit (use "git add" and/or "git commit -a")

Houd er rekening mee dat de juiste resultaatcodes worden geretourneerd, zodat u deze opdrachten in andere scripts kunt gebruiken. Dit kan worden geverifieerd na het uitvoeren van opdrachten met:

echo $?

Wees voorzichtig met exploits voor variabele uitbreidingenomdat ik niet zeker was van het gedeelte --grep=$1. Het zou misschien --grep="$1"moeten zijn, maar ik weet niet zeker of dat de regex-scheidingstekens zou verstoren (ik sta open voor suggesties).


Antwoord 12

Dit antwoord heeft veel te danken aan Klemen Slavič. Ik zou gewoon gereageerd hebben op het geaccepteerde antwoord, maar ik heb nog niet genoeg vertegenwoordiger 🙁

Je zou ook een git-alias kunnen toevoegen om de stash-ref te vinden en deze in andere aliassen te gebruiken voor show, apply, drop, etc.

[alias]
    sgrep = "!f() { ref=$(git --no-pager stash list | grep "$1" | cut -d: -f1 | head -n1); echo ${ref:-<no_match>}; }; f"
    sshow = "!f() { git stash show $(git sgrep "$1") -p; }; f"
    sapply = "!f() { git stash apply $(git sgrep "$1"); }; f"
    sdrop = "!f() { git stash drop $(git sgrep "$1"); }; f"

Merk op dat de reden voor de ref=$( ... ); echo ${ref:-<no_match>};patroon is zo dat er geen lege string wordt geretourneerd, waardoor sshow, sapply en sdrop de laatste stash targeten in plaats van te falen zoals men zou verwachten.


Antwoord 13

Alias
Dit kan een meer directe syntaxis zijn voor Unix-achtige systemen zonder dat het in een functie hoeft te worden ingekapseld.
Voeg het volgende toe aan ~/.gitconfig onder [alias]

sshow = !sh -c 'git stash show stash^{/$*} -p' -
sapply = !sh -c 'git stash apply stash^{/$*}' -
ssave = !sh -c 'git stash save "${1}"' -

Gebruik:
pas regex

toe

Voorbeeld:
git sshow MySecretStash

Het koppelteken aan het einde zegt invoer van standaardinvoer overnemen.


Antwoord 14

Gebruik een klein bash-script om het nummer van de stash op te zoeken. Noem het “gitapply”:

NAME="$1"
if [[ -z "$NAME" ]]; then echo "usage: gitapply [name]"; exit; fi
git stash apply $(git stash list | grep "$NAME" | cut -d: -f1)

Gebruik:

gitapply foo

…waar foo een substring is van de naam van de stash die je wilt hebben.


Antwoord 15

Gebruik git stash save NAMEom op te slaan.

Dan… kun je dit script gebruiken om te kiezen wat je wilt toepassen (of laten verschijnen):

#!/usr/bin/env ruby
#git-stash-pick by Dan Rosenstark
# can take a command, default is apply
command = ARGV[0]
command = "apply" if !command
ARGV.clear
stashes = []
stashNames = []
`git stash list`.split("\n").each_with_index { |line, index|
    lineSplit = line.split(": ");
    puts "#{index+1}. #{lineSplit[2]}"
    stashes[index] = lineSplit[0]
    stashNames[index] = lineSplit[2]
}
print "Choose Stash or ENTER to exit: "
input = gets.chomp
if input.to_i.to_s == input
    realIndex = input.to_i - 1
    puts "\n\nDoing #{command} to #{stashNames[realIndex]}\n\n"
    puts `git stash #{command} #{stashes[realIndex]}`
end

Ik vind het leuk om de namen van de stashes te zien en te kiezen. Ik gebruik ook Zshell en wist eerlijk gezegd niet hoe ik sommige van de bovenstaande Bash-aliassen moest gebruiken;)

Opmerking: zoals Kevin zegt, moet je in plaats daarvan tags en cherry-picks gebruiken.


Antwoord 16

Dit is een manier om dit te bereiken met PowerShell:

<#
.SYNOPSIS
Restores (applies) a previously saved stash based on full or partial stash name.
.DESCRIPTION
Restores (applies) a previously saved stash based on full or partial stash name and then optionally drops the stash. Can be used regardless of whether "git stash save" was done or just "git stash". If no stash matches a message is given. If multiple stashes match a message is given along with matching stash info.
.PARAMETER message
A full or partial stash message name (see right side output of "git stash list"). Can also be "@stash{N}" where N is 0 based stash index.
.PARAMETER drop
If -drop is specified, the matching stash is dropped after being applied.
.EXAMPLE
Restore-Stash "Readme change"
Apply-Stash MyStashName
Apply-Stash MyStashName -drop
Apply-Stash "stash@{0}"
#>
function Restore-Stash  {
    [CmdletBinding()]
    [Alias("Apply-Stash")]
    PARAM (
        [Parameter(Mandatory=$true)] $message,         
        [switch]$drop
    )
    $stashId = $null
    if ($message -match "stash@{") {
        $stashId = $message
    }
    if (!$stashId) {
        $matches = git stash list | Where-Object { $_ -match $message }
        if (!$matches) {
            Write-Warning "No stashes found with message matching '$message' - check git stash list"
            return
        }
        if ($matches.Count -gt 1) {
            Write-Warning "Found $($matches.Count) matches for '$message'. Refine message or pass 'stash{@N}' to this function or git stash apply"
            return $matches
        }
        $parts = $matches -split ':'
        $stashId = $parts[0]
    }
    git stash apply ''$stashId''
    if ($drop) {
        git stash drop ''$stashId''
    }
}

Meer details hier


Antwoord 17

in mijn vissenschelp

function gsap
  git stash list | grep ": $argv" | tr -dc '0-9' | xargs git stash apply
end

gebruik

gsap name_of_stash


Antwoord 18

git stash applywerkt ook met andere refs dan stash@{0}. U kunt dus gewone tagsgebruiken om een blijvende naam te krijgen. Dit heeft ook het voordeel dat je het niet per ongeluk git stash dropof git stash popkunt plaatsen.

Dus je kunt een alias pstash(ook wel “persistent stash”) als volgt definiëren:

git config --global alias.pstash '!f(){ git stash && git tag "$1" stash && git stash drop; }; f'

Je kunt nu een getagde stash maken:

git pstash x-important-stuff

en showen applyhet opnieuw zoals gewoonlijk:

git stash show x-important-stuff
git stash apply x-important-stuff

Antwoord 19

Hier laat op het feest, maar als je VSCode gebruikt, is een snelle manier om dit te doen, door het commandopalet (CTRL / CMD + SHIFT + P) te openen en “Pop Stash” te typen. stash op naam zonder de noodzaak om git CLI te gebruiken


Antwoord 20

Ik denk niet dat er een manier is om een stash bij zijn naam te krijgen.

Ik heb een bash-functie gemaakt die dit doet.

#!/bin/bash
function gstashpop {
  IFS="
"
  [ -z "$1" ] && { echo "provide a stash name"; return; }
  index=$(git stash list | grep -e ': '"$1"'$' | cut -f1 -d:)
  [ "" == "$index" ] && { echo "stash name $1 not found"; return; }
  git stash apply "$index"
}

Voorbeeld van gebruik:

[~/code/site] on master*
$ git stash push -m"here the stash name"
Saved working directory and index state On master: here the stash name
[~/code/site] on master
$ git stash list
stash@{0}: On master: here the stash name
[~/code/site] on master
$ gstashpop "here the stash name"

Ik hoop dat het helpt!


Antwoord 21

Voor alles behalve het maken van stash, zou ik een andere oplossing voorstellen door fzfte introduceren als een afhankelijkheid. Ik raad aan om 5 minuten van je tijd te nemen en er kennis mee te maken, want het is over het algemeen een geweldige productiviteitsverhoger.

Hoe dan ook, een gerelateerd fragment van hun voorbeeldenpaginamet het zoeken naar stash. Het is heel gemakkelijk om de scriptlet te wijzigen om extra functionaliteit toe te voegen (zoals een stash-toepassing of drop-out):

fstash() {
    local out q k sha
    while out=$(
            git stash list --pretty="%C(yellow)%h %>(14)%Cgreen%cr %C(blue)%gs" |
            fzf --ansi --no-sort --query="$q" --print-query \
                --expect=ctrl-d,ctrl-b); do
        mapfile -t out <<< "$out"
        q="${out[0]}"
        k="${out[1]}"
        sha="${out[-1]}"
        sha="${sha%% *}"
        [[ -z "$sha" ]] && continue
        if [[ "$k" == 'ctrl-d' ]]; then
            git diff $sha
        elif [[ "$k" == 'ctrl-b' ]]; then
            git stash branch "stash-$sha" $sha
            break;
        else
            git stash show -p $sha
        fi
    done
}

Antwoord 22

dit is een snelle installatie die ik heb gemaakt en werkt voor mij, ik hoop dat het ook voor jou zal werken:

Stel dat ik een aangepast/lokaal script in mijn package.json-projectbestand heb dat ik niet naar een externe repo wil pushen

{
   // ... package.json stuff
   "scripts": {
       "custom": "ts-node a_ts_test_file.ts"
   }
}

Dus ik besluit deze wijziging te stashen wanneer ik mijn branch of iets dergelijks wil pushen en de stash pop tot mijn volgende “git push”.

Dus …

  1. Je moet een nieuwe git-alias maken:
# dev is the "stash tag"
# To stash current working directory
git config --global alias.sh "stash -m 'dev'"
  1. Je moet je ~.bashrzof ~.zshrcbewerken als je zsh of oh-my-zsh gebruikt, voeg dan de volgende alias toe:
# Apply stash "tagged" $(X) where X is substring of "git stash list" output filtered by output that contains "dev".
# I didn't use git stash apply because "dev" tag isn't unique, so it's a need to pop the stash and ensure to create a new one alias set on first step
alias gitsh="git stash pop $(git stash list | grep 'dev' | cut -d ':' -f 1) || echo 'nope'"
  1. Veel plezier 🙂

Om je werkmap te pushen met tag “dev”: git sh
Voor het ophalen van uw stashed gewijzigd van stash met de tag “dev”: sitsh

( Het is een klein script dat ik in vijf minuten heb gemaakt en het werkt voor mij, als het faalt … repareer het! 😉 )

Other episodes