git stash的使用

https://git-scm.com/docs/git-stash

在git svn的时候使用,提交记录的时候,有部分文件的修改不需要commit。

在向svn进行git svn dcommit的时候,必须保存本地目录是clean的。所以需要进行stash,然后在dcommit

dcommit之后,需要在git stash aply

之前一直都在使用git stash 以及git stash apply

但是一直没有深入的研究,今天发现git stash是是会覆盖掉之前的stash的[stash apply仅仅取出最近的一次stash]

git stash --help  查看帮助手册

Use git stash when you want to record the current state of the working directory and the index, but want to go back to a clean working directory. The command saves your local modifications away and reverts the working directory to match the HEAD commit.

The modifications stashed away by this command can be listed with git stash list, inspected with git stash show, and restored (potentially on top of a different commit) with git stash apply. Calling git stash without any arguments is equivalent to git stash save. A stash is by default listed as "WIP on branchname …", but you can give a more descriptive message on the command line when you create one.

The latest stash you created is stored in refs/stash; older stashes are found in the reflog of this reference and can be named using the usual reflog syntax (e.g. stash@{0} is the most recently created stash, stash@{1} is the one before it,stash@{2.hours.ago} is also possible).

git stash list

查看之前缓存的所有stash

$ git stash list
stash@{0}: WIP on temp: 36b0f5f 删除HSDataFrameManager类中多余的代码      //第二次的stash,覆盖了第一次【git stash apply的时候,只能出现这一次的,上一次的不会出现】
stash@{1}: WIP on temp: 36b0f5f 删除HSDataFrameManager类中多余的代码      //第一次的stash
stash@{2}: WIP on temp: c723e17 接收到消息的时候,打印出消息类型,如果消息内部有
stash@{3}: WIP on temp: 18fa2a3 连接通讯模块时,需要将主窗体的窗口句柄传递给通讯

temp是分支的名字  

第0个和第1个虽然看起来完全一样,但实际上是不同的

git stash list --date=local

$ git stash list --date=local
stash@{Fri Dec 15 15:20:55 2017}: On local: event log
stash@{Tue Dec 12 18:12:25 2017}: On local: chile configuration
stash@{Thu Nov 30 13:50:49 2017}: On local: RDCLIS-191

git stash show

查看list中的某一次stash

$ git stash show stash@{0}
ZBMYun/SourceCode/ZITakerHS/ZITaker/SystemConfig.ini | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

$ git stash show stash@{1}
ZBMYun/SourceCode/ZITakerHS/ZITaker/UI/Main.cs | 2 +-
ZBMYun/SourceCode/ZITakerHS/ZITaker/ZbmStorage_Component.ini | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)

git stash show stash@{0} -u

添加-u参数可以输出某一次stash的所有文件差异对比

 git stash apply

可以apply指定的stash,如果你不指定的话,默认apply最近一次的stash

If you want to apply one of the older stashes, you can specify it by naming it, like this: git stash apply stash@{2}.

If you don’t specify a stash, Git assumes the most recent stash and tries to apply it:

git stash drop

$ git stash list
stash@{0}: WIP on local: 63b9f1b DebugInfoManager类,在FormMain加载的时候需要主
stash@{1}: WIP on svn: 78ab728 设备第一次上线后,直接发送采集数据,在这种情况下

$ git stash drop stash@{0}
Dropped stash@{0} (1136bc142780259d8541c7e3a605ff2250cc9427)

git stash pop

pop [--index] [-q|--quiet] [<stash>]

Remove a single stashed state from the stash list and apply it on top of the current working tree state, i.e., do the inverse operation of git stash save. The working directory must match the index.

Applying the state can fail with conflicts; in this case, it is not removed from the stash list. You need to resolve the conflicts by hand and call git stash drop manually afterwards.

If the --index option is used, then tries to reinstate not only the working tree’s changes, but also the index’s ones. However, this can fail, when you have conflicts (which are stored in the index, where you therefore can no longer apply the changes as they were originally).

When no <stash> is given, stash@{0} is assumed, otherwise <stash> must be a reference of the form stash@{<revision>}.

git stash save

 这样的log更具有可读性

Options:

save [-p|--patch] [-k|--[no-]keep-index] [-u|--include-untracked] [-a|--all] [-q|--quiet] [<message>]

Save your local modifications to a new stash, and run git reset --hard to revert them.

The <message> part is optional and gives the description along with the stashed state.

For quickly making a snapshot, you can omit both "save" and <message>, but giving only <message> does not trigger this action to prevent a misspelled subcommand from making an unwanted stash.

If the --keep-index option is used, all changes already added to the index are left intact.

If the --include-untracked option is used, all untracked files are also stashed and then cleaned up with git clean, leaving the working directory in a very clean state.

If the --all option is used instead then the ignored files are stashed and cleaned in addition to the untracked files.

What's the difference between git stash save and git stash push?

git stash save accepts a single non-option argument — the stash message.

git stash push accepts the message with option -m and accepts a list of files to stash as arguments.

What's the difference between git stash and git stash save?

From the docs:

Calling git stash without any arguments is equivalent to git stash save.

What is the purpose of git stash create and git stash store?

问题:

From the documentation at git-scm, there are two git stash commands that mention relevance to scripting, but not general use:

create

Create a stash (which is a regular commit object) and return its object name, without storing it anywhere in the ref namespace. This is intended to be useful for scripts. It is probably not the command you want to use; see "save" above.

store

Store a given stash created via git stash create (which is a dangling merge commit) in the stash ref, updating the stash reflog. This is intended to be useful for scripts. It is probably not the command you want to use; see "save" above.

Supposing that we are considering the context of automated scripts, what advantages do git stash create and git stash store give me over the usual git stash save and friends? 

解答1:

You can use git stash create when you're writing scripts that need to stash as an implementation detail and you don't want to disturb the user's stash reflog.

Depending on what happens next, you might (in the case of error, say) decide you do want to disturb the stash reflog after all, at which point you can use git stash store.

Obviously a regular stash can be implemented in terms of create then store, but I can also imagine it being used in a hypothetical update-branch command that does something like this:

git stash create
git fetch
git rebase
git stash apply

在TortoiseGit中查看

假如stash的节点,是在一个月前的某个commit上进行stash。那么查看日志,建议按照时间排序,先定位到stash,通过分支线去找到父节点。

正常情况下,日志还是需要按照topo-order来排序 

Why is a stash represented as 2 commits?

因为index上可能会有一些缓存过的,比如git add但是没有commit的。而工作目录的内容和index有可能是不一样的。

Short answer

git stash differentiates between the changes you have on your index and the one you have in the working tree and creates commits for both of them.

Long answer

Some background

Using git it's possible that the changes you have in your working tree (the files your directly work with) are different from the changes you have on the index.

Adding only a limited number of files to the index, or with git add --patch even adding single changed lines in a file will leave your index in a different state as the working tree.
This is a good thing, because it enables you to create commits which focus on one specific task/feature.

It's even possible that you have changes on your index which aren't anymore part of your working tree. You can test it by adding some changes to the index (git add), manually removing them from the file and then creating a commit (git commit).
The commit will still contain the changes you added in the first place, although they don't exist in your working tree anymore.

If you have trouble understanding the difference between the working tree and the index you can take a look at this question.

What exactly is happening?

Now the statement from the beginning should make more sense. One "stash commit" contains all changes you had in your working tree (the files you directly work with) and the other contains the changes you had added to your index.

By default git stash pop or git stash apply only tries to reinstate the changes you had in your working tree and ignores the changes you had on the index. It's possible to tell git stash to try reinstating your index too by using the --index flag (git stash (pop|apply) --index).

https://stackoverflow.com/questions/3689838/whats-the-difference-between-head-working-tree-and-index-in-git

https://stackoverflow.com/questions/27012878/why-is-a-stash-represented-as-2-commits

在TortoiseGit中查看stash list

右键TortoiseGit-->Stash list

在打开的窗口中,右键选中某一个stash,然后compare with previous revision ,选择parent 1就可以

How can I rename a git stash?

 

Let's assume your stash list looks like this:

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

First, you must remove stash entry which you want to rename:

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

Now just add it again with new message using sha of commit returned after dropping:

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

And that's it:

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

This solution requires git 1.8.4 or later, and yes, it works with dirty working directory too.

操作之前

 

 操作之后,发现日志栏的显示不会变化。但是git stash list显示的内容变化了。

 stash@{0}:  route debugger

但是对比使用 git stash save "route debugger"又有点不同,git stash save显示的git stash list如下,并且日志栏也是正常显示的

 stash@{0}: On local-com-1505: route debugger

原文地址:https://www.cnblogs.com/chucklu/p/4793715.html