git stash 恢复changes 是什么操作

10 个迅速提升你 Git 水平的提示 - 开源中国社区
当前访客身份:游客 [
10 个迅速提升你 Git 水平的提示
英文原文:
Recently we published a couple of tutorials to get you familiar with
and . The commands that we discussed were about enough to help a developer survive in the Git world. In this post, we will try to explore how to manage your time effectively and make full use of the features that Git provides.
Note: Some commands in this article include part of the command in square brackets (e.g. git add -p [file_name]). In those examples, you would insert the necessary number, identifier, etc. without the square brackets.
最近我们推出了两个教程:和&. 我们所讨论的命令足够一个开发者在Git使用方面游刃有余。在这篇文章中,我们试图探索怎样有效的管理你的时间和充分的使用Git提供的功能。
注:本文中,一些命令包含了方括号中的部分内容(例如:git add -p [file_name]).在这些示例中,你将插入必要的数字、标示符等等,如果没有方括号。
1. Git Auto Completion
If you run Git commands through the command line, it’s a tiresome task to type in the commands manually every single time. To help with this, you can enable auto completion of Git commands within a few minutes.
To get the script, run the following in a Unix system:
curl&/git/git/master/contrib/completion/git-completion.bash&-o&~/.git-completion.bash
Next, add the following lines to your ~/.bash_profile file:
if&[&-f&~/.git-completion.bash&];&then
&&&&.&~/.git-completion.bash
Although I have mentioned this earlier, I can not stress it enough: If you want to use the features of Git fully, you should definitely shift to the command line interface!
1.&Git自动补全
假使你使用命令行工具运行Git命令,那么每次手动输入各种命令是一件很令人厌烦的事情。 为了解决这个问题,你可以启用Git的自动补全功能,完成这项工作仅需要几分钟。
为了得到这个脚本,在Unix系统下运行以下命令:
curl&/git/git/master/contrib/completion/git-completion.bash&-o&~/.git-completion.bash
然后,添加下面几行到你的 ~/.bash_profile 文件中:
if&[&-f&~/.git-completion.bash&];&then
&&&&.&~/.git-completion.bash
尽管早些时候我们已经提到这个,但是强调的不够充分。如果你想使用git的全部功能特性, 你绝对应该切换到命令行界面!
2. Ignoring Files in Git
Are you tired of compiled files (like .pyc) appearing in your Git repository? Or are you so fed up that you have added them to Git? Look no further, there is a way through which you can tell Git to ignore certain files and directories altogether. Simply create a file with the name .gitignore and list the files and directories that you don’t want Git to track. You can make exceptions using the exclamation mark(!).
my_db_config/
其它翻译版本:1(点击译者名切换)
2. 在 Git 中忽略文件
你是不是很烦那些编译过的文件 (比如 .pyc) 出现在你的 Git 仓库中?或者说你已经受够了已经把它们都加进了 Git 仓库?好了,这有个办法可以让你告诉 Git 忽略掉那些特定的文件和文件夹。只需要创建一个名为&.gitignore 然后列出那些你不希望 Git 跟踪的文件和文件夹。你还可以添加例外,通过使用感叹号(!)。
my_db_config/
3. Who Messed With My Code?
It’s the natural instinct of human beings to blame others when something goes wrong. If your production server is broke, it’s very easy to find out the culprit — just do a git blame. This command shows you the author of every line in a file, the commit that saw the last change in that line, and the timestamp of the commit.
git&blame&[file_name]
And in the screenshot below, you can see how this command would look on a bigger repository:
3. 是谁弄乱了我的代码?
当事情出错时,先去指责别人是人类的天性之一。如果你的产品服务器挂了,使用git blame命令可以很容易找出罪魁祸首。这个命令可以将文件中的每一行的作者、最新的变更提交和提交时间展示出来。
git&blame&[file_name]
在下面的截图中你可以看到命令是如何在更大的目录中搜寻。
4. Review History of the Repository
We had a look at the use of git log in a previous tutorial, however, there are three options that you should know about.
--oneline - Compresses the information shown beside each commit to a reduced commit hash and the commit message, all shown in a single line.
--graph - This option draws a text-based graphical representation of the history on the left hand side of the output. It’s of no use if you are viewing the history for a single branch.
--all - Shows the history of all branches.
Here’s what a combination of the options looks like:
4. 查看仓库历史记录
上一节我们已经学习了如何使用 git log ,不过,这里还有三个你应该知道的选项。
--oneline- 压缩模式,在每个提交的旁边显示经过精简的提交哈希码和提交信息,以一行显示。
--graph- 图形模式,使用该选项会在输出的左边绘制一张基于文本格式的历史信息表示图。如果你查看的是单个分支的历史记录的话,该选项无效。
--all- 显示所有分支的历史记录
把这些选项组合起来之后,输出看起来会像这样:
5. Never Lose Track of a Commit
Let’s say you committed something you didn’t want to and ended up doing a hard reset to come back to your previous state. Later, you realize you lost some other information in the process and want to get it back, or at least view it. This is where git reflog can help.
A simple git log shows you the latest commit, its parent, its parent’s parent, and so on. However, git reflog is a list of commits that the head was pointed to. Remember that it’s
it’s not a part of your repository and not included in pushes or merges.
If I run git log, I get the commits that are a part of my repository:
However, a git reflog shows a commit (b1b0ee9 – HEAD@{4}) that was lost when I did a hard reset:
5. 绝对不要丢失对Commit的跟踪
假设你不小心提交了些你不想要的东西,不得不做一次强制重置来恢复到之前的状态。然后,你意识到在这一过程中你丢失了其它一些信息并且想要把它们找回来,或者至少瞅一眼。这正是git reflog可以做到的。
一个简单的git log命令可以为你展示最后一次commit,以及它的父亲,还有它父亲的父亲等等。而git reflog则列出了head曾经指向过的一系列commit。要明白它们只存在于你本机中;而不是你的版本仓库的一部分,也不包含在push和merge操作中。
如果我运行git log命令,我可以看到一些commit,它们都是我仓库的一部分:
然而,一个git reflog命令则展示了一次commit (b1b0ee9–HEAD@{4}),它正是我刚才进行强制重置时弄丢的:
6. Staging Parts of a Changed File for a Commit
It is generally a good practice to make feature-based commits, that is, each commit must represent a feature or a bug fix. Consider what would happen if you fixed two bugs, or added multiple features without committing the changes. In such a situation situation, you could put the changes in a single commit. But there is a better way: Stage the files individually and commit them separately.
Let’s say you’ve made multiple changes to a single file and want them to appear in separate commits. In that case, we add files by prefixing -p to our add commands.
git&add&-p&[file_name]
Let’s try to demonstrate the same. I have added three new lines to file_name and I want only the first and third lines to appear in my commit. Let’s see what a git diff shows us.
And let’s see what happes when we prefix a -p to our add command.
It seems that Git assumed that all the changes were a part of the same idea, thereby grouping it into a single hunk. You have the following options:
Enter y to stage that hunk
Enter n to not stage that hunk
Enter e to manually edit the hunk
Enter d to exit or go to the next file.
Enter s to split the hunk.
In our case, we definitely want to split it into smaller parts to selectively add some and ignore the rest.
As you can see, we have added the first and third lines and ignored the second. You can then view the status of the repository and make a commit.
6. 暂存文件的部分改动
一般情况下,创建一个基于特性的提交是比较好的做法,意思是每次提交都必须代表一个新特性的产生或者是一个bug的修复。如果你修复了两个bug,或是添加了多个新特性但是却没有提交这些变化会怎样呢?在这种情况下,你可以把这些变化放在一次提交中。但更好的方法是把文件暂存(Stage)然后分别提交。
例如你对一个文件进行了多次修改并且想把他们分别提交。这种情况下,你可以在 add 命令中加上&-p 参数
git&add&-p&[file_name]
我们来演示一下在&file_name&文件中添加了3行文字,但只想提交第一行和第三行。先看一下&git diff&显示的结果:
然后再看看在 add 命令中添加 -p 参数是怎样的?
看上去,Git 假定所有的改变都是针对同一件事情的,因此它把这些都放在了一个块里。你有如下几个选项:
输入 y 来暂存该块
输入 n 不暂存
输入 e 手工编辑该块
输入 d 退出或者转到下一个文件
输入 s 来分割该块
在我们这个例子中,最终是希望分割成更小的部分,然后有选择的添加或者忽略其中一部分。
正如你所看到的,我们添加了第一行和第三行而忽略了第二行。之后你可以查看仓库状态之后并进行提交。
7. Squash Multiple Commits
When you submit your code for review and create a pull request (which happens often in open source projects), you might be asked to make a change to your code before it’s accepted. You make the change, only to be asked to change it yet again in the next review. Before you know it, you have a few extra commits. Ideally, you could squash them into one using the rebase command.
git&rebase&-i&HEAD~[number_of_commits]
If you want to squash the last two commits, the command that you run is the following.
git&rebase&-i&HEAD~2
On running this command, you are taken to an interactive interface listing the commits and asking you which ones to squash. Ideally, you pick the latest commit and squash the old ones.
You are then asked to provide a commit message to the new commit. This process essentially re-writes your commit history.
7. 压缩多个Commit
当你提交代码进行代码审查时或者创建一次pull request (这在开源项目中经常发生),你的代码在被接受之前会被要求做一些变更。于是你进行了变更,并且直到下一次审查之前你没有再次被要求进行变更过。在你知道又要进行变更之前,你已经有了一些额外的commit。理想情况下,你可以用rebase命令把多个commit压缩成一个。
git&rebase&-i&HEAD~[number_of_commits]
如果你想要压缩最后两个commit,你需要运行下列命令。
git&rebase&-i&HEAD~2
运行该命令时,你会看到一个交互界面,列出了许多commit让你选择哪些需要进行压缩。理想情况下,你选择最后一次commit并把其它老commit都进行压缩。
然后会要求你为新的commit录入提交信息。这一过程本质上重写了你的commit历史。
8. Stash Uncommitted Changes
Let’s say you are working on a certain bug or a feature, and you are suddenly asked to demonstrate your work. Your current work is not complete enough to be committed, and you can’t give a demonstration at this stage (without reverting the changes). In such a situation, git stash comes to the rescue. Stash essentially takes all your changes and stores them for further use. To stash your changes, you simply run the following-
To check the list of stashes, you can run the following:
git&stash&list
If you want to un-stash and recover the uncommitted changes, you apply the stash:
git&stash&apply
In the last screenshot, you can see that each stash has an indentifier, a unique number (although we have only one stash in this case). In case you want to apply only selective stashes, you add the specific identifier to the apply command:
git&stash&apply&stash@{2}
8. Stash未提交的更改
你正在修改某个bug或者某个特性,又突然被要求展示你的工作。而你现在所做的工作还不足以提交,这个阶段你还无法进行展示(不能回到更改之前)。在这种情况下, git stash可以帮助你。stash在本质上会取走所有的变更并存储它们为以备将来使用。stash你的变更,你只需简单地运行下面的命令-
希望检查stash列表,你可以运行下面的命令:
git&stash&list
如果你想要解除stash并且恢复未提交的变更,你可以进行apply stash:
git&stash&apply
在屏幕截图中,你可以看到每个stash都有一个标识符,一个唯一的号码(尽管在这种情况下我们只有一个stash)。如果你只想留有余地进行apply stash,你应该给apply添加特定的标识符:
git&stash&apply&stash@{2}
9. Check for Lost Commits
Although reflog is one way of checking for lost commits, it’s not feasible in large repositories. That is when the fsck (file system check) command comes into play.
git&fsck&--lost-found
Here you can see a lost commit. You can check the changes in the commit by running git show [commit_hash] or recover it by running git merge [commit_hash].
git fsck has an advantage over reflog. Let’s say you deleted a remote branch and then cloned the repository. With fsck you can search for and recover the deleted remote branch.
9.检查丢失的提交
尽管 reflog 是唯一检查丢失提交的方式。但它不是适应用于大型的仓库。那就是 fsck(文件系统检测)命令登场的时候了。
git&fsck&--lost-found
这里你可以看到丢掉的提交。你可以通过运行 git show [commit_hash] 查看提交之后的改变或者运行git merge [commit_hash] 来恢复到之前的提交。
git fsck 相对reflog是有优势的。比方说你删除一个远程的分支然后关闭仓库。 用fsck 你可以搜索和恢复已删除的远程分支。1075人阅读
PC知识(16)
转自:http://blog.csdn.net/lincyang/article/details/
今天用git pull来更新代码,遇到了下面的问题:
提示已经很友好了,从网友处得到的答案直接帮我解决问题。
通常遇到这个问题,你可以直接commit你的修改;但我这次不想这样。
看看git stash是如何做的。
git stash pop
接下来diff一下此文件看看自动合并的情况,并作出相应修改。
git stash: 备份当前的工作区的内容,从最近的一次提交中读取相关内容,让工作区保证和上次提交的内容一致。同时,将当前的工作区内容保存到Git栈中。
git stash pop: 从Git栈中读取最近一次保存的内容,恢复工作区的相关内容。由于可能存在多个Stash的内容,所以用栈来管理,pop会从最近的一个stash中读取内容并恢复。
git stash list: 显示Git栈内的所有备份,可以利用这个列表来决定从那个地方恢复。
git stash clear: 清空Git栈。此时使用gitg等图形化工具会发现,原来stash的哪些节点都消失了。
2.放弃本地修改,直接覆盖之
git reset --hard
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:3289290次
积分:27307
积分:27307
排名:第144名
原创:20篇
转载:978篇
评论:383条
(2)(1)(4)(5)(10)(1)(7)(13)(6)(4)(3)(9)(10)(3)(13)(6)(22)(14)(13)(19)(26)(50)(9)(12)(13)(47)(22)(31)(29)(18)(26)(12)(6)(23)(5)(12)(4)(10)(12)(79)(44)(86)(12)(9)(7)(21)(6)(10)(14)(23)(30)(4)(1)(3)(5)(3)(9)(2)(16)(3)(17)(5)(5)(8)(2)(3)(3)(20)(10)(14)(3)在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 liststash@{0}: WIP on temp: 36b0f5f 删除HSDataFrameManager类中多余的代码 & & &//第二次的stash,覆盖了第一次【git stash apply的时候,只能出现这一次的,上一次的不会出现】stash@{1}: WIP on temp: 36b0f5f 删除HSDataFrameManager类中多余的代码 & & &//第一次的stashstash@{2}: WIP on temp: c723e17 接收到消息的时候,打印出消息类型,如果消息内部有stash@{3}: WIP on temp: 18fa2a3 连接通讯模块时,需要将主窗体的窗口句柄传递给通讯
temp是分支的名字 &
第0个和第1个虽然看起来完全一样,但实际上是不同的
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 liststash@{0}: WIP on local: 63b9f1b DebugInfoManager类,在FormMain加载的时候需要主stash@{1}: WIP on svn: 78ab728 设备第一次上线后,直接发送采集数据,在这种情况下
$ git stash drop stash@{0}Dropped stash@{0} (259da605ff)
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 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&}.
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.
阅读(...) 评论()7386人阅读
开发人员常常遇到这种情况:花了几天时间一直在做一个新功能,已经改了差不多十几个文件,突然有一个bug需要紧急解决,然后给一个build测试组。在Git问世之前基本上靠手动备份,费时且容易出错。
git stash命令简而言之就是帮助开发人员暂时搁置当前已做的改动,倒退到改动前的状态,进行其他的必要操作(比如发布,或者解决一个bug,或者branch,等等),之后还可以重新载入之前搁置的改动,很cool吧?
首先,用git add把所有的改动加到staging area。
接着用git stash把这些改动搁置。
到这里,当前工作平台就回复到改动之前了。该干嘛干嘛,此处省略1万字。
需要找回之前搁置的改动继续先前的工作了?
git stash apply&即可。
也可以用&git stash list&来查看所有的搁置版本(可能搁置了很多次,最好不要这样,容易搞混)
在出现一个搁置栈的情况下,比如如果你想找回栈中的第2个,可以用&git stash apply stash@{1}
如果想找回第1个,可以用&git stash pop
如果想删除一个stash,git stash drop &id&
删除所有stash,git stash clear
我第一次用这个命令时被坑过,经过是这样的:我发现有一个类是多余的,想删掉它又担心以后需要查看它的代码,想保存它但又不想增加一个脏的提交。这时我想到了git
stash,于是那一天我执行了下这个命令就回去睡觉了。 第二天我继续在这个目录里工作,coding了半天才发现前一天的修改都不见了,暂存区里也没有任何昨天修改的纪录。是我忘了保存了吗?
相信git老手们早就看出问题所在了,修改消失了并不是因为我忘了保存,而是git stash在保存完当前工作目录和暂存区以后,会用HEAD重置这两者。因为我昨天的修改没有提交,HEAD指向的是前天的版本,所以stash以后工作目录和暂存区就会被前天的的版本所重置。
正确的做法应该是在git stash后再执行git
stash apply,当前的工作目录就恢复回来了。
git stash apply相当于利用过去贮藏(stashed)的工作目录快照,恢复当前的工作目录。如果工作目录在贮藏之后发生了变化,恢复时就会产生冲突(conflict),这种情况下git
stash apply会对工作目录进行merge操作。
和merge一样,git stash apply之前要保持当前目录是干净的(没有未提交的改变),否则会保错:
error: Your local changes to the following files would be overwritten by merge: Please, commit your changes or stash them before you can merge.
git stash apply只能恢复工作目录,如果想把暂存区也按照贮藏时的暂存区恢复的话,可以加上--index,如果暂存区恢复时发生冲突了会怎么办呢?嘿嘿,它会直接报错不允许你这么做:
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:731189次
积分:5587
积分:5587
排名:第3342名
原创:67篇
转载:35篇
评论:71条
(1)(1)(1)(1)(1)(4)(1)(3)(9)(10)(7)(10)(5)(3)(1)(5)(11)(9)(6)(1)(8)(4)

我要回帖

更多关于 stashed changes 的文章

 

随机推荐