Jak nazwać i odzyskać stash po imieniu w git?

Zawsze miałem wrażenie, że możesz nadać skrytce nazwę, wykonując git stash save stashname, którą później możesz zastosować, wykonując git stash apply stashname. Ale wygląda na to, że w tym przypadku wszystko, co się dzieje, to to, że stashname zostanie użyty jako opis skrytki.

Nie da się nazwać skrytki? Jeśli nie, to co polecacie, aby osiągnąć równoważną funkcjonalność? Zasadniczo mam mały schowek, który chciałbym okresowo stosować, ale nie chcę zawsze polować w git stash list Co to jest prawdziwy numer skrytki to.
 965
Author: Geoffrey Hale, 2012-06-30

15 answers

Możesz znaleźć skrytkę po nazwie używając składni wyrażeń regularnych git do adresowania obiektów:

stash^{/<regex>}
:/<regex>

Na przykład podczas zapisywania skrytki z nazwą zapisu:

git stash save "guacamole sauce WIP"

... możesz użyć wyrażenia regularnego do adresowania skrytki:

git stash apply stash^{/guacamo}

Zastosuje najmłodszy schowek, który pasuje do wyrażenia regularnego guacamo. W ten sposób nie musisz wiedzieć, pod jakim numerem znajduje się skrytka w stosie, musisz tylko znać jego nazwę. Nie ma składni tersera dla to, ale możesz utworzyć alias w pliku .gitconfig:

[alias]
sshow = "!f() { git stash show stash^{/$*} -p; }; f"
sapply = "!f() { git stash apply stash^{/$*}; }; f"

Możesz użyć git sapply <regex>, Aby zastosować skrytkę (bez upuszczania).
możesz użyć git sshow <regex>, aby wyświetlić: pliki zmienione, wstawione i usunięte

EDIT: Props to this StackOverflow answer on how to use bash arguments in Git aliases.

EDIT 2: ta odpowiedź zawiera drop i list aliasy, ale od tego czasu je usunąłem, ponieważ drop wymaga składni stash@{n} podczas gdy list w ogóle nie filtrowałem staszy. Jeśli ktoś wie, jak rozwiązać hash stash SHA-1 do ref stash, to mogę zaimplementować również inne polecenia.

EDIT 3: Per isyi's sugestia dodałem flagę patcha, aby pokazać, jaka jest zawartość skrytki podczas wyświetlania.

 1192
Author: Klemen Slavič,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 11:47:32

Tak to się robi:

git stash save "my_stash"

Gdzie "my_stash" jest nazwą skrytki...

Kilka przydatnych rzeczy, które warto wiedzieć: wszystkie stasze są przechowywane w stosie. "Type": "content"]}

git stash list

To będzie lista wszystkich Twoich stashes.

Aby zastosować skrytkę i usunąć ją ze stosu skrytek, możesz dać,

git stash pop stash@{n}

Aby zastosować skrytkę i zachować ją w stosie skrytek, wpisz:

git stash apply stash@{n}

Gdzie n w indeksie zmiany ukrytej.

 337
Author: Sri Murthy Upadhyayula,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-09-16 18:08:23

Możesz zamienić skrytkę W gałąź, jeśli uważasz, że jest wystarczająco ważna:

git stash branch <branchname> [<stash>]

Ze strony man:

Tworzy i sprawdza nową gałąź o nazwie począwszy od zatwierdzenia, w którym pierwotnie został utworzony , stosuje zmiany zapisane w do nowego drzewa roboczego i indeksu, a następnie usuwa , jeśli zakończy się pomyślnie. Gdy nie podano , stosuje najnowszy.

Jest to przydatne, jeśli gałąź, na której uruchomiłeś git stash save zmienił się na tyle, że git stash apply zawiedzie z powodu konfliktów. Ponieważ skrytka jest nakładana na commit, który był głową w momencie uruchomienia git stash, przywraca pierwotny stan przechowywany bez konfliktów.

Możesz później przerobić tę nową gałąź do innego miejsca, które jest potomkiem miejsca, w którym byłeś, gdy schowałeś.

 67
Author: Adam Dymitruk,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-11-05 17:37:06

Stasze nie mają być trwałymi rzeczami, jak chcesz. Prawdopodobnie lepiej byłoby używać tagów na commitach. Zbuduj coś, co chcesz ukryć. Zrób z tego zobowiązanie. Utwórz znacznik dla tego commita. Następnie cofnij gałąź do HEAD^. Teraz, gdy chcesz ponownie zastosować ten Schowek, możesz użyć git cherry-pick -n tagname (-n is --no-commit).

 34
Author: Kevin Ballard,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-06-29 21:39:34

git stash save jest przestarzałe teraz, zamiast tego możesz użyć git stash push -m "message"

Można tak:

git stash push -m "message"

Gdzie "wiadomość" to nazwa skrytki...

 20
Author: EssaidiM,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-03-29 15:08:43

Jeśli szukasz tylko lekkiego sposobu na zapisanie niektórych lub wszystkich zmian w swojej obecnej kopii roboczej, a następnie zastosowanie ich później do woli, rozważ plik łatki:

# save your working copy changes
git diff > some.patch

# re-apply it later
git apply some.patch

Od czasu do czasu zastanawiam się, czy powinienem używać do tego stashów, a potem widzę takie rzeczy jak szaleństwo powyżej i jestem zadowolony z tego, co robię:)

 15
Author: Pat Niemeyer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-11-10 16:06:23

Alias

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

Użycie

git sapply "<regex>"

  • kompatybilny z Git dla Windows

Edit: trzymałem się oryginalnego rozwiązania, ale widzę, dlaczego większość wolałaby wersję Etana Reisnera (powyżej). Tak dla przypomnienia:

sapply = "!f() { git stash apply \"$(git stash list | grep -E \"$*\" | awk \"{ print $ 1; }\" | sed -n \"s/://;1p\")\"; }; f"
 7
Author: Vlastimil Ovčáčík,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-12-22 20:56:29

Odpowiedź ta zawdzięcza wiele Klemenowi Slavičowi. Ja bym po prostu skomentował zaakceptowaną odpowiedź, ale nie mam jeszcze dość rep: (

Możesz również dodać alias git, aby znaleźć stash ref i użyć go w innych aliasach dla show, apply, drop, itp.

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

Zauważ, że powodem wzorca ref=$( ... ); echo ${ref:-<no_match>}; jest to, że pusty łańcuch nie jest zwracany, co spowodowałoby, że ssow, sapply i sdrop skierowałyby najnowszy stash zamiast fail, jak można by się spodziewać.

 5
Author: Nathanael,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-01-11 01:30:02

Alias Może to być bardziej bezpośrednia składnia dla systemów uniksopodobnych bez konieczności hermetyzacji w funkcji. Dodaj następujący tekst do~/.gitconfig under [alias]

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

Użycie: sapply regex

Przykład: git ssow MySecretStash

Myślnik na końcu mówi take input ze standardowego wejścia.

 3
Author: Rohanthewiz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-08-22 17:55:45

Mam te dwie funkcje w moim pliku .zshrc:

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)
}

Używanie ich w ten sposób:

gitstash nice

gitstashapply nice
 2
Author: iWheelBuy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-07-09 05:59:35

Dla wszystkiego poza tworzeniem stash ' a, zaproponowałbym inne rozwiązanie, wprowadzając fzf jako zależność. Polecam poświęcenie 5 minut swojego czasu i zapoznanie się z nim, ponieważ jest już po wszystkim-wszystko to świetny wzmacniacz produktywności.

W każdym razie, powiązany fragment z ich przykładowej strony oferującej wyszukiwanie skrytki. Bardzo łatwo jest zmienić sciptlet, aby dodać dodatkowe funkcjonalności (takie jak aplikacja stash lub upuszczanie): {]}

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
}
 1
Author: laur,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-09-10 11:58:54

Jest to jeden ze sposobów na osiągnięcie tego za pomocą 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''
    }
}

Więcej szczegółów tutaj

 1
Author: Geoffrey Hudik,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-07-20 19:35:00

Użyj git stash save NAME, aby zapisać.

Więc... możesz użyć tego skryptu, aby wybrać, który ma zostać zastosowany (lub pop):
#!/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

Lubię być w stanie zobaczyć nazwy staszy i wybrać. Również używam Zshell i szczerze mówiąc nie wiedziałem, jak korzystać z niektórych aliasów Basha powyżej;)

Uwaga: Jak mówi Kevin, powinieneś używać tagów i Cherry-picks zamiast tego.

 1
Author: Dan Rosenstark,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-07-20 20:31:06

Użyj małego skryptu bash, aby sprawdzić numer skrytki. Nazwijmy to "gitapply":

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

Użycie:

gitapply foo

...gdzie foo jest podłańcuchem nazwy skrytki, którą chcesz.

 1
Author: Will Sheppard,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-02-19 12:56:59

Szkoda, że git stash apply stash^{/<regex>} nie działa (w rzeczywistości nie przeszukuje listy skrytek, Zobacz komentarze Pod zaakceptowaną odpowiedzią ).

Tutaj znajdują się zamienniki drop-in, które przeszukują git stash list przez regex, aby znaleźć pierwszą (najnowszą) stash@{<n>}, a następnie przekazać ją 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")

Zwróć uwagę, że odpowiednie kody wynikowe są zwracane, więc możesz używać tych poleceń w innych skryptach. Można to sprawdzić po uruchomieniu poleceń z:

echo $?

Po prostu uważaj o exploitach rozszerzeń zmiennych ponieważ nie byłem pewien co do części --grep=$1. Może powinno być --grep="$1", ale nie jestem pewien, czy to mogłoby kolidować z ogranicznikami regex (jestem otwarty na sugestie).

 1
Author: Zack Morris,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-09-21 14:45:53