web-dev-qa-db-fra.com

Comment nommer et récupérer une cachette par son nom dans git?

J'ai toujours eu l'impression que vous pouviez donner un nom à une cachette en faisant git stash save stashname, que vous pourriez ensuite appliquer en faisant git stash apply stashname. Mais il semble que dans ce cas, tout ce qui se produit est que stashname sera utilisé comme description de la dissimulation.

N'y a-t-il pas moyen de nommer une cachette? Si non, que recommanderiez-vous pour obtenir une fonctionnalité équivalente? J'ai essentiellement une petite réserve que j'aimerais régulièrement appliquer, mais je ne veux pas toujours avoir à chercher dans git stash list quel est son numéro de réserve.

1049
Suan

Voici comment vous le faites:

git stash save "my_stash"

où "my_stash" est le nom de la cachette ...

Quelques choses plus utiles à savoir: Tous les stash sont stockés dans une pile . Tapez:

git stash list

Cela listera toutes vos caches.

Pour appliquer une cachette et la retirer de la pile de cachette, vous pouvez donner,

git stash pop stash@{n}

Pour appliquer une cachette et la conserver dans la pile de cachette, tapez:

git stash apply stash@{n}

Où n dans l'index du changement caché.

430

git stash save est obsolète à partir de 2.15.x/2.16, vous pouvez utiliser plutôt git stash Push -m "message" 

Vous pouvez procuder comme ceci:

git stash Push -m "message" 

où "message" est votre nom de réserve ...

89
EssaidiM

Vous pouvez transformer une réserve en une branche si vous le jugez suffisamment important:

git stash branch <branchname> [<stash>]

depuis la page de manuel:

Cela crée et extrait une nouvelle branche nommée <nombranchée> à partir de la validation à laquelle le <stash> a été créé à l'origine, applique les modifications enregistrées dans <stash> au nouvel arbre et index de travail, puis supprime le <stash> si cela se produit. se termine avec succès. Quand aucun <stash> n'est donné, applique le dernier.

Ceci est utile si la branche sur laquelle vous avez exécuté git stash save a suffisamment changé pour que l'application de git stash échoue en raison de conflits. Comme la cachette est appliquée par-dessus le commit qui était HEAD au moment où git stash a été exécutée, il restaure l'état initialement caché sans aucun conflit.

Vous pouvez ensuite rebaser cette nouvelle branche vers un autre endroit qui est un descendant de l'endroit où vous étiez lorsque vous avez caché.

76
Adam Dymitruk

Les caches ne sont pas conçues pour être permanentes, comme vous le souhaitez. Vous seriez probablement mieux servi en utilisant des balises sur les commits. Construisez la chose que vous voulez cacher. Engagez-vous dessus. Créez une étiquette pour ce commit. Ensuite, rétablissez votre branche à HEAD^. Maintenant, lorsque vous souhaitez réappliquer cette réserve, vous pouvez utiliser git cherry-pick -n tagname (-n est --no-commit).

35
Lily Ballard

Si vous cherchez simplement un moyen léger d’enregistrer une partie ou la totalité de vos modifications de copie de travail actuelles et de les réappliquer ultérieurement à volonté, envisagez un fichier de correctif:

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

# re-apply it later
git apply some.patch

De temps en temps, je me demande si je devrais utiliser des cachettes pour cela, puis je vois des choses comme la folie ci-dessus et je suis content de ce que je fais :) 

29
Pat Niemeyer

J'ai ces deux fonctions dans mon fichier .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)
}

En les utilisant de cette façon:

gitstash Nice

gitstashapply Nice
12
iWheelBuy

Alias

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

Usage

git sapply "<regex>"

  • compatible avec Git pour Windows

Edit: je suis resté fidèle à ma solution originale, mais je vois pourquoi la majorité préférerait la version d'Etan Reisner (ci-dessus). Donc, juste pour l'enregistrement:

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

Il est regrettable que git stash apply stash^{/<regex>} ne fonctionne pas (il ne fait pas de recherche dans la liste de dissimulation, voir les commentaires sous réponse acceptée ).

Voici les remplacements instantanés qui recherchent git stash list par regex pour trouver le premier (le plus récent) stash@{<n>}, puis le transmettent à 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")

Notez que les codes de résultat appropriés sont renvoyés afin que vous puissiez utiliser ces commandes dans d'autres scripts. Ceci peut être vérifié après avoir exécuté des commandes avec:

echo $?

Faites juste attention aux exploits de développement de variable parce que je n’étais pas sûr de la partie --grep=$1. Cela devrait peut-être être --grep="$1" mais je ne suis pas sûr que cela interfère avec les délimiteurs de regex (je suis ouvert aux suggestions).

6
Zack Morris

Cette réponse doit beaucoup à Klemen Slavič. J'aurais juste commenté la réponse acceptée mais je n'ai pas encore assez de représentants :(

Vous pouvez également ajouter un alias git pour trouver la référence de masquage et l’utiliser dans d’autres alias pour afficher, appliquer, déposer, 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"

Notez que la raison du modèle ref=$( ... ); echo ${ref:-<no_match>}; est qu’une chaîne vide n’est pas renvoyée, ce qui obligerait sshow, sapply et sdrop à cibler le dernier stash au lieu d’échouer comme prévu.

5
Nathanael

Alias ​​ Cela pourrait être une syntaxe plus directe pour les systèmes de type Unix sans avoir besoin d'encapsuler dans une fonction . Ajouter ce qui suit à ~/.gitconfig sous [alias]

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

Usage: sapply regex

Exemple: git sshow MySecretStash

Le trait d'union à la fin indique de prendre une entrée de l'entrée standard.

3
Rohanthewiz

Utilisez un petit script bash pour rechercher le numéro de la réserve. Appelez ça "gitapply":

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

Usage:

gitapply foo

... où foo est une sous-chaîne du nom de la réserve que vous voulez.

3
Will Sheppard

Pour toute chose en plus de la création de stash, je proposerais une autre solution en introduisant fzf en tant que dépendance. Nous vous recommandons de prendre 5 minutes de votre temps et de vous y familiariser, car c’est un excellent stimulant de la productivité.

Quoi qu'il en soit, un extrait connexe de leur page exemples offrant une recherche cachée. Il est très facile de changer le sciptlet pour ajouter des fonctionnalités supplémentaires (telles que l'application stash ou drop):

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
laur

C’est un moyen de réaliser cela à l’aide de 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''
    }
}

Plus de détails ici

1
Geoffrey Hudik

Utilisez git stash save NAME pour enregistrer.

Ensuite ... vous pouvez utiliser ce script pour choisir lequel appliquer (ou apparaître):

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

J'aime pouvoir voir les noms des cachettes et choisir. Aussi, j'utilise Zshell et franchement, je ne savais pas comment utiliser certains des alias Bash ci-dessus;

Remarque: comme le dit Kevin, vous devriez plutôt utiliser des balises et des sélections.

1
Dan Rosenstark

Et ça?

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

dans ma coquille de poisson

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

utilisation

gsap name_of_stash

0
Matsumoto Kazuya

En retard pour la partie, mais si vous utilisez VSCode, un moyen rapide de le faire est d'ouvrir la palette de commandes (CTRL/CMD + SHIFT + P) et de taper "Pop Stash", vous pourrez récupérer votre stash par nom sans avoir besoin d'utiliser git CLI

0
Alexandre Gomes

git stash apply fonctionne également avec d'autres références que stash@{0}. Vous pouvez donc utiliser tags pour obtenir un nom persistant. Cela a aussi l’avantage que vous ne pouvez pas accidentellement git stash drop ou git stash pop le. 

Donc, vous pouvez définir un alias pstash (aka "stash persistant") comme ceci:

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

Maintenant, vous pouvez créer une réserve marquée:

git pstash x-important-stuff

et show et apply comme d'habitude:

git stash show x-important-stuff
git stash apply x-important-stuff
0
A.H.