Як я можу перейменувати скриньку git?


202

У мене є скринька з неправильним ім’ям. Я хотів би виправити ім’я, щоб воно було точно.

Як я можу перейменувати сховище?


5
попс і зберегти його знову з іншою назвою?
Bartlomiej Lewandowski

5
Знову вискакувати та зберігати не завжди є варіантом, тому що приховування даних може бути засноване на застарілому стані та призводити до конфліктів при появі. (Застарілий стан навіть не має існувати ніде в історії.)
Том

Відповіді:


258

Припустимо, ваш список сховищ виглядає так:

$ git stash list
stash@{0}: WIP on master: Add some very important feature 
stash@{1}: WIP on master: Fix some silly bug

По-перше, ви повинні видалити схований запис, який ви хочете перейменувати:

$ git stash drop stash@{1}
Dropped stash@{1} (af8fdeee49a03d1b4609f294635e7f0d622e03db)

Тепер просто додайте його знову до нового повідомлення, використовуючи шафи комітів, повернуті після випадання:

$ git stash store -m "Very descriptive message" af8fdeee49a03d1b4609f294635e7f0d622e03db

І це все:

$ git stash list
stash@{0}: Very descriptive message
stash@{1}: WIP on master: Add some very important feature

Це рішення вимагає git 1.8.4 або пізнішої версії, і так, воно також працює з брудною робочою директорією.


3
git show stash@{0}як і раніше показує стару інформацію згодом. Як це виправити? (Будь ласка, зауважте, що тоді приховується інша SHA.)
Тіно

4
Краще зайнятися хешем git showі почати з цього git stash store. Тоді з git stash listвами побачите старий і новий скрипт. Нарешті, ви можете почистити стару скриньку за допомогою git stash drop.
хогі

6
чи не втратить зміни залишок засипки від git?
Shravya Boggarapu

4
@ShravyaBoggarapu, ні, git не видаляє фіксацію, поки git gcне запущено. Після stash dropтого, як ви можете легко знайти цю звичайно недоступну фіксацію за допомогою git fsck | grep commitкоманди.
qzb

2
@ ÐerÆndi просто застосувати та зберегти - це простий варіант, але він не працює, коли зміни не можуть бути застосовані повторно через конфлікти. Тим часом викидання та зберігання робіт за будь-яких обставин. Я ще раз перевірив своє рішення - воно працює чудово в останній версії git (2.17.0).
qzb

62

Якщо ви не зробите це вручну або не зробите вдосконалення для Git, ви можете використовувати псевдонім:

git config --global alias.stash-rename '!_() { rev=$(git rev-parse $1) && git stash drop $1 || exit 1 ; git diff-index --quiet HEAD; s=$?; [ $s != 0 ] && git stash save "tmp stash from stash-rename"; git stash apply $rev && shift && git stash save "$@" && [ $s != 0 ] && git stash pop stash@{1}; }; _'

Використання: " git stash-rename <stash> [save options] [<message>]"

З [save options]будь-яким варіантом git stash save:[-p|--patch] [-k|--[no-]keep-index] [-q|--quiet] [-u|--include-untracked] [-a|--all]

Приклад:

$ git stash list
stash@{0}: On master: Pep8 format
stash@{1}: On master: co other than master with local changes
stash@{2}: On master: tests with deployAtEnd

# Let's say I want to rename the stash@{2} adding an issue reference:
$ git stash-rename stash@{2} NXP-13971-deployAtEnd

$ git stash list
stash@{0}: On master: NXP-13971-deployAtEnd
stash@{1}: On master: Pep8 format
stash@{2}: On master: co other than master with local changes

Це спрацює, навіть якщо у вас є місцеві нестандартні зміни :)

EDIT 2016/02/22

Спрощений сценарій, кредити на qzb , https://stackoverflow.com/a/35549615/515973

git config --global alias.stash-rename '!_() { rev=$(git rev-parse $1) && git stash drop $1 || exit 1 ; git stash store -m "$2" $rev; }; _'

Використання: " git stash-rename <stash> [<message>]"


1
Дивовижно! Ще крутіше, якщо ти міг би зробитиgit stash-rename 'tests with deployAtEnd' 'NXP-13971-deployAtEnd'
mikemaccana

3
тож відповідь - 1) чиста робоча копія, 2) застосувати копію, яку ви хочете перейменувати, 3) відкинути її зі списку скриньки, 4) створити нову скриньку з правильним повідомленням.
gcb

2
Для уточнення, ви перейменовуєте останню скриньку, і після такої дії вона стає верхньою скринькою?
onebree

2
Я видаляю скриньку для перейменування, зберігаю поточні зміни, якщо такі є, відтворюю видалений прихований файл із потрібним ім'ям, повторно застосовую поточні зміни, якщо такі є.
Жульєн Карсік

3
Ця версія перевіряє наявність обох аргументів, щоб не просто випадково скинути ваш останній приклад. Також потрібен лише номер скриньки, а не весь stash@{0}довідник. gist.github.com/jdforsythe/f248bf6c72fc020225cc3e315a32e922 git config --global alias.stash-rename '!_() { if [ -z \"$1\" ] || [ -z \"$2\" ]; then echo \"git stash-rename 0 NewName\" && echo \"\" && git stash list && exit 1; else stash=\"stash@{$1}\"; rev=$(git rev-parse \"${stash}\"); git stash drop \"${stash}\" || exit 1; git stash store -m \"$2\" \"$rev\" || exit 1; git stash list; fi }; _'
jdforsythe

6

Це дуже просто. По-перше, скасуйте останню скриньку за допомогою:

git stash pop

Після цього yo може зберегти скриньку з налаштованою назвою таким чином:

git stash save "your explanatory name"

Я сподіваюся, що це стане в нагоді для вас. :)


Перейменований приклад може бути не останнім.
mikemaccana

Пальці вгору, оскільки це більш просто (ТІЛЬКИ) для останньої скриньки.
Кайхуа

3

Я не думаю, що це можливо зробити. Була запропонована пропозиція щодо перейменування сховищ, але вона ще не була втілена в життя.

Моя загальна ідея:

  1. Реалізуйте нову git reflog updateкоманду, яка оновлює повідомлення, пов’язане з певним записом відмивання. Для цього нова update_reflog_ent()функція (в reflog.c ) змінила б повідомлення, пов’язане з певним записом відмивання, оновити. update_reflog()Функція буде використовувати for_each_reflog_ent()зupdate_reflog_ent фактично робити зміни.

  2. Тоді git stash renameкоманді потрібно буде лише зателефонувати git reflog updateз відповідним посиланням та новим повідомленням.

Або, звичайно, ви могли б викинути скриньку і зробити git stash save [message]


3

На користь читача, ось розширення до прийнятої та правильної відповіді .

Якщо ви не тільки хочете виправити скриньку повідомлення, а також хочете виправити повідомлення про фіксацію скриньки, таким чином

git stash list

і

git log --oneline -1 stash

обидва згодні з тим, що показано, вам потрібно трохи більше. Можливо, є кращий спосіб зробити це, але цей рецепт тут легко зрозуміти, сподіваюся.

Щоб мати змогу це зробити, git commit --amendвам потрібно бути на підказці відділення. Звідси рішення:

git checkout -b scratch stash@{1}
git stash drop stash@{1}
git commit --amend -m "$MESSAGE"
git stash store -m "$MESSAGE" HEAD
git checkout master
git branch -D scratch

Пояснили:

  • Створіть нову (ще не існуючу) гілку "подряпин" з "питання про сховище" та перейдіть до неї
  • Вийміть стару скриньку. Це безпечно, оскільки ми все ще маємо це на гілці.
  • Використовуйте git commit --amendдля заміни повідомлення про фіксацію, це змінює SHA "скриньки у питанні"
  • Зберігайте сховище на основі відповіді qzb
  • Переключіться назад (що передбачає, що ви прийшли з "майстра") та очищення

Недоліки:

  • Це тимчасово перемикає гілки. Тож цей рецепт можна застосовувати лише тоді, коли git status --porcelainвін чистий (читайте: нічого не видає)

  • Він перераховує таємницю, тому змінена скринька стає stash@{0}

  • Вам потрібно ввести $MESSAGEдвічі або використовувати якусь змінну середовища (у прикладі MESSAGE:)

  • Потрібно знайти невикористану назву гілки

Існують способи зробити це без перемикання гілок, але це виходить за межі цієї відповіді.

Приклад

git init scratch
cd scratch
for a in A B C D; do date >$a; git add $a; git commit -m $a; done
for a in X Y; do echo $a > Z; git stash save --all; done
git log --oneline --graph --decorate --all; git stash list

Вихідні дані

*-.   e0e281b (refs/stash) WIP on master: 8bdcc32 D
|\ \  
| | * 4d62f52 untracked files on master: 8bdcc32 D
| * 096f158 index on master: 8bdcc32 D
|/  
* 8bdcc32 (HEAD, master) D
* c84c659 C
* 49bb2da B
* b1852c6 A
stash@{0}: WIP on master: 8bdcc32 D
stash@{1}: WIP on master: 8bdcc32 D

Тепер, не змінюючи прихильність (зверніть увагу: SHA нижче буде відрізнятися у вас):

git stash drop stash@{1}
git stash store -m ...changed... 2fbf9007dfdfb95ae269a19e13b8b9ca3e24181c
git log --oneline --graph --decorate --all; git stash list

Вихідні дані

*-.   2fbf900 (refs/stash) WIP on master: 8bdcc32 D
|\ \  
| | * 246dc5c untracked files on master: 8bdcc32 D
| * 80c5ea0 index on master: 8bdcc32 D
|/  
* 8bdcc32 (HEAD, master) D
* c84c659 C
* 49bb2da B
* b1852c6 A
stash@{0}: ...changed...
stash@{1}: WIP on master: 8bdcc32 D

Як бачите, stash@{0}усе ще відображається як 2fbf900 (refs/stash) WIP on master: 8bdcc32 Dу git log. Якщо ви уважно подивитесь, то побачите, що декілька комітетів змінили SHA. Це пов’язано з тим, як обробляють таємницю (батьки включаються до складу SHA, а їхні ставки є батьківськими).

Виправте, що:

git checkout -b scratch stash
git stash drop
git commit --amend -m ...changed...
git stash store -m ...changed... HEAD
git checkout master
git branch -D scratch
git log --oneline --graph --decorate --all; git stash list

Вихідні дані

*-.   4d55186 (refs/stash) ...changed...
|\ \  
| | * 246dc5c untracked files on master: 8bdcc32 D
| * 80c5ea0 index on master: 8bdcc32 D
|/  
* 8bdcc32 (HEAD, master) D
* c84c659 C
* 49bb2da B
* b1852c6 A
stash@{0}: ...changed...
stash@{1}: WIP on master: 8bdcc32 D

Як ви також можете бачити, refs/stashзмінився SHA теж.


Варто зазначити: це знищує індекс, який було збережено з оригінальним сховищем, замінюючи його новим індексом, який відповідає батьківському комітету оригінальної скрині. Якщо хтось не планував використовувати оригінальний збережений індекс (або він вже збігався з початковим початковим сховищем), це не проблема.
Торека

1

Ось модифікована версія псевдоніму Жульєна, яка дозволяє вам належним чином мати справу з On <branch>префіксом, як правило, прихованим для приховування імен:

git config --global alias.stash-rename '!_() { newmsg="$1" && stash=${2:-"stash@{0}"} && newbranch="$3" && sha=$(git rev-parse "$stash") && olddesc="$(git stash list --format=%gs -1 "$stash")" && newdesc="$(if [[ "$newbranch" = "." ]]; then echo "$newmsg"; else if [[ -n "$newbranch" ]]; then echo "On $newbranch: $newmsg"; else if [[ "$olddesc" =~ ":" ]]; then echo "$(echo "$olddesc" | cut -f1 -d":"): $newmsg"; else echo "$newmsg"; fi; fi; fi)" && git stash drop "$stash" > /dev/null || exit 1; git stash store -m "$newdesc" "$sha" && git stash list; }; _'

Синтаксис:

git stash-rename <new-name> [<stash> [<new-branch-name> | .]]

Приклад використання:

repo[master] % touch tmp && git add tmp && git stash save first
Saved working directory and index state On master: first
HEAD is now at bd62064 Initial commit
repo[master] % touch tmp && git add tmp && git stash save second
Saved working directory and index state On master: second
HEAD is now at bd62064 Initial commit
repo[master] % git stash list
stash@{0}: On master: second
stash@{1}: On master: first
repo[master] % git stash-rename renamed
stash@{0}: On master: renamed
stash@{1}: On master: first
repo[master] % git stash-rename also-renamed stash@{1}
stash@{0}: On master: also-renamed
stash@{1}: On master: renamed
repo[master] % git stash-rename branch-changed stash@{0} new-branch
stash@{0}: On new-branch: branch-changed
stash@{1}: On master: renamed
repo[master] % git stash-rename branch-name-persists
stash@{0}: On new-branch: branch-name-persists
stash@{1}: On master: renamed
repo[master] % git stash-rename no-branch stash@{0} .
stash@{0}: no-branch
stash@{1}: On master: renamed
repo[master] % git stash-rename renamed
stash@{0}: renamed
stash@{1}: On master: renamed
repo[master] % git stash-rename readd-branch stash@{0} develop
stash@{0}: On develop: readd-branch
stash@{1}: On master: renamed

Більшість команд призначені для розбору аргументів і з'ясування того, що слід зробити з назвою гілки. Застосовуються такі gitінструменти:

  • git rev-parse <stash> щоб знайти SHA скриньки.
  • git stash list --format=%gs -1 <stash>щоб знайти тему рефлогу схованки. Зауважте, що це відрізняється від повідомлення фіксації скриньки, яке не змінюється цією командою. Тема рефлогу - це те, що відображається git stash list, і ви можете змінити предмет рефлогу, не змінюючи хеші комітетів, пов’язаних із статистикою. Однак ви завжди можете знайти оригінальне повідомлення про фіксацію, тому не використовуйте git stash-renameдля видалення конфіденційної інформації!
  • git stash drop <stash>відкинути старе посилання на сховище (але у нас все ще є SHA, тому воно не втрачено).
  • git stash store -m <new-message> <sha>щоб зберегти нове посилання на сховище з тією ж інформацією про фіксацію, але іншою темою перегляду .
  • git stash listперерахувати сташі після закінчення операції. Зауважте, що нові скриньки завжди висуваються на початок списку. Необхідно було б повторно проштовхнути всі скриньки перед захованням, що цікавиться, щоб відновити його початкове положення.

0

Найпростіший спосіб: поп ваш скрипт з git stash pop, а потім збережіть його знову за допомогою git stash save your-name


Перейменований приклад може бути не останнім.
mikemaccana
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.