有点乱,以后再详细整理,本文是按日期记得笔记。
一, 在GitHub新建托管项目
1,要托管到github,那你就应该要有一个属于你自己的github帐号,所以你应该先到github.com注册
打开浏览器
在地址栏输入地址:github.com
填写用户名、邮箱、密码
点击Sign up即可简单地注册
完成注册,进入github平台,
2,点击new repositories 新建一个新项目(你也可以加入到一个已有的项目)
3,新建项目的操作,其实很简单,输入项目名就可以直接Create了,
4,此时的界面,我想大家都应该很熟悉了。点击右边栏的剪切板图标,记录下你的项目地址。
5,上传项目至GitHub
首先你要在本地计算机中安装一个git客户端。
你可以直接使用GitHub客户端,也可以用其他。
因本人使用的是msysgit,所以这里以msysgit作为介绍(msysgit同样也是目前最为广泛实用的工具之一)。
打开msysgit.github.io
下载并安装最新版本的msysgit
安装完成后,进入到要托管的项目根目录,
右键启动Git Bash命令行
如下图所示
输入git clone 接着将先前记录下来的地址复制到后面,回车
将下载下来的项目文件夹的所有文件及文件夹,包括.git文件夹在内,全部拷贝到你的托管项目的根目录(或者将你的托管项目拷贝到该目录)
cd test
进入到该托管项目的根目录。
输入
git add .
将改动的地方添加到版本管理器
输入
git commit -m "changes log"
提交到本地的版本控制库里,
引号里面是你对本次提交的说明信息。
最后输入
git push -u origin master
将你本地的仓库提交到你的github账号里,
此时会要求你输入你的github的账号和密码。
回到你的github.com中的项目页。
里面的文件是不是已经发生改变了?
至此,
github项目已经成功更新。
更多的github的操作,你可以自己慢慢的体会。但有了这第一步认识,我相信你以后的摸索会更加容易得多。
最后push的时候有有问题,这样处理#$ unset SSH_ASKPASS
另外一种,只要知道你github的地址,可以不用在上面先创建,直接在本地操作,完了push就可以,过程如下:
touch README.rm
git init
git add .
git commit -m 'init'
git remote add origin xxxxxx
git push -u origin master
二,一些常用的命令
1 查看远程分支
git branch -a
2,查看本地分支
git branch
3,创建分支
git branch test
4,把分支推到远程分支
git push origin test
5,切换分支到test
git checkout test
6,删除本地分支 git branch -d xxxxx
7,查看提交日志git log
8,查看状态git status
先要切换到要推送的分支
git push origin local_branch:remote_branch
git push origin v1.0.0:v1.0.0
git status命令可以列出当前目录所有还没有被git管理的文件和被git管理且被修改但还未提交(git commit)的文件.。
9,查看远程库git remote -v
10,添加远程库
git remote add pratice https://github.com/zhuihouyigemeng/prace.git
11,删除远程库git remote rm pratice,远程库在哪里(githug页面哪里能看到)?
12,git config --global user.name "Your Name"
$ git config --global user.email wirelessqa.me@gmail.com
13,在本地新建一个分支: git branch Branch1
切换到你的新分支: git checkout Branch1
将新分支发布在github上: git push origin Branch1
在本地删除一个分支: git branch -d Branch1
在github远程端删除一个分支:git push origin :Branch1 (分支名前的冒号代表删除)
Git分支下的目录结构一样,的作用是什么?本地提交是作用是什么?本地提交和本地没提交有什么区别?Git remote add远程库是不是和本地添加一个文件夹一样?
14,git remote show origin查看远程库的意思
15,要新建并切换到该分支,运行git checkout 并加上 -b 参数:
$ git checkout -b iss53
16,创建+切换分支:git checkout -bname
合并某分支到当前分支:git merge name
删除分支:git branch -d name
17,本地分支重命名git branch -m delelop develop
18,推送到git push origin develop
19,删除远程分支git push --delete origin haverest_v2.0
20, 比如,如果要将开发中的分支(develop),合并到稳定分支(master),
首先切换的master分支:git checkout master。
然后执行合并操作:git merge develop。
21,设置全局变量
git config --global user.name "zuihouyigemeng"
git config --global ylyylsy@126.com
git config --global http.postBuffer 524288000
git config --global http.postBuffer 20480000
git config --list
git config core.autocrlf false
22,分支管理
创建分支很简单:git branch <分支名>
切换分支 git checkout <分支名>,该语句和上一个语句可以和起来用一个语句表示:git checkout -b <分支名>
合并分支,比如,如果要将开发中的分支(develop),合并到稳定分支(master),首先切换的master分支:git checkout master。然后执行合并操作:git merge develop。如果有冲突,会提示你,调用git status查看冲突文件。这里有两种方法比较常用,git reset 和gitstash
分支衍合,分支衍合和分支合并的差别在于,分支衍合不会保留合并的日志,不留痕迹,而 分支合并则会保留合并的日志。要将开发中的分支(develop),衍合到稳定分支(master)。首先切换的master分支:git checkout master。然后执行衍和操作:git rebase develop。
如果有冲突,会提示你,调用git status查看冲突文件。
所有冲突解决后,git rebase --continue 提交更改。
删除分支
执行git branch -d <分支名>
如果该分支没有合并到主分支会报错,可以用以下命令强制删除git branch -D <分支名>
23,git remote add命令用于添加远程主机。
24,初始化git仓库git init
25.git remote add origin git@xx.xx.xx.xx:repos/xxx/xxx/xxx.git
26.git push origin 本地分支:远程分支
27,git log -p 查看日志和改动。
经试验发现,可以查看上次的修改。,
git log
git log <file> # 查看该文件每次提交记录
git log -p <file> # 查看每次详细修改内容的diff
git log -p -2 # 查看最近两次详细修改内容的diff
git log --stat #查看提交统计信
28,git commit -a
git commit -a这个命令可以直接提交所有修改,省去了你git add和git diff和git commit的工序,注意:无法把新增文件或文件夹加入进来,所以,如果你新增了文件或文件夹,那么就要老老实实的先git add .,再git commi
29,如何检查修改过的文件
Git clone (加-b应该可以指定分支)
好像与合并有关系
git pull --rebase origin master
如何解决failed to push some refs to git
出现错误的主要原因是github中的README.md文件不在本地代码目录中
可以通过如下命令进行代码合并【注:pull=fetch+merge]
git pull --rebase origin master
30,git log -p -2 显示最近两次提交的区别,这个命令我常用GIT DIFF HEAD来代替,以后可以用LOG了,好像方便一点。
31,用 --oneline 选项来查看历史记录的简洁的版本。
git log --oneline
32,用 --graph 选项,查看历史中什么时候出现了分支、合并。以下为相同的命令,开启了拓扑图选项
git log --oneline --graph33,逆向查看
git log --reverse --oneline
warning: LF will be replaced by CRLF
windows中的换行符为 CRLF, 而在linux下的换行符为LF,所以在执行add . 时出现提示,解决办法:
[plain] view plain copy
$ rm -rf .git // 删除.git
$ git config --global core.autocrlf false //禁用自动转换
然后重新执行:
[plain] view plain copy
$ git init
$ git add .
git config core.autocrlf false
解决Unable to rewind rpc post data
在使用git提交项目到服务器上时,会提示Unable to rewind rpc post data–try increasing http.postBuffer
1 2 | git commit -m "commit" git push origin |
在提交的项目内容都很小时没有问题,如果文件较大,则会提交失败,提示
1 | Unable to rewind rpc post data - try increasing http.postBuffer |
需要将http.postBuffer设置成适合的值
1 2 | git config --global http.postBuffer 20480000 git config --list |
再次提交即可成功。
$ git add file.txt
$ git commit
注意:提交注释里已经有一些关于合并的信息了,通常是用这些默认信息,但是你可以添加一些你想要的注释。
上面这些就是你要做一个简单合并所要知道的,但是git提供更多的一些信息来 帮助解决冲突。
三、撒销一个合并
如果你觉得你合并后的状态是一团乱麻,想把当前的修改都放弃,你可以用下面的命令回到合并之前的状态:
$ git reset --hard HEAD
或者你已经把合并后的代码提交,但还是想把它们撒销:
$ git reset --hard ORIG_HEAD
但是刚才这条命令在某些情况会很危险,如果你把一个已经被另一个分支合并的分支给删了,那么以后在合并相关的分支时会出错。
关于撤销的更多内容请参考《git reset简介》
四、快速向前合并
还有一种需要特殊对待的情况,在前面没有提到。通常,一个合并会产生一个合并提交(commit),把两个父分支里的每一行内容都合并进来。
但是,如果当前的分支和另一个分支没有内容上的差异,就是说当前分支的每一个提交(commit)都已经存在另一个分支里了,git就会执行一个“快速向前"(fast forward)操作;git不创建任何新的提交(commit),只是将当前分支指向合并进来的分支。
五、在合并过程中得到解决冲突的协助
git会把所有可以自动合并的修改加入到索引中去,所以git diff只会显示有冲突的部分.它使用了一种不常见的语法:
$ git diff
diff --cc file.txt
index 802992c,2b60207..0000000
--- a/file.txt
+++ b/file.txt
@@@ -1,1 -1,1 +1,5 @@@
++<<<<<<< HEAD:file.txt
+Hello world
++=======
+ Goodbye
++>>>>>>> 77976da35a11db4580b80ae27e8d65caf5208086:file.txt
回忆一下, 在我们解决冲突之后,得到的提交会有两个而不是一个父提交: 一个父提交是当前分支提交前的HEAD,;另外一个父提交是被合并分支的HEAD,被暂时存在MERGE_HEAD.
在合并过程中, 索引中保存着每个文件的三个版本.三个"文件暂存(file stage)"中的每一个都代表了文件的不同版本:
$ git show :1:file.txt # 两个分支共同祖先中的版本.
$ git show :2:file.txt # HEAD中的版本.
$ git show :3:file.txt # MERGE_HEAD中的版本.
当你使用git diff去显示冲突时,它在工作树(work tree), 暂存2(stage 2)和暂存3(stage 3)之间执行三路diff操作,只显示那些两方都有的块(换句话说,当一个块的合并结果只从暂存2中得到时,是不会被显示出来的;对于暂存3来说也是一样).
上面的diff结果显示了file.txt在工作树,暂存2和暂存3中的差异. git不在每行前面加上单个'+'或者'-',相反地,它使用两栏去显示差异:第一栏用于显示第一个父提交与工作目录文件拷贝的差异,第二栏用于显示第二个父提交与工作文件拷贝的差异. (参见git diff-files中的"COMBINED DIFF FORMAT"取得此格式详细信息.)
在用直观的方法解决冲突之后(但是在更新索引之前), diff输出会变成下面的样子:
$ git diff
diff --cc file.txt
index 802992c,2b60207..0000000
--- a/file.txt
+++ b/file.txt
@@@ -1,1 -1,1 +1,1 @@@
- Hello world
-Goodbye
++Goodbye world
上面的输出显示了解决冲突后的版本删除了第一个父版本提供的"Hello world"和第二个父版本提供的"Goodbye",然后加入了两个父版本中都没有的"Goodbye world".
一些特别diff选项允许你对比工作目录和三个暂存中任何一个的差异:
$ git diff -1 file.txt # 与暂存1进行比较
$ git diff --base file.txt # 与上相同
$ git diff -2 file.txt # 与暂存2进行比较
$ git diff --ours file.txt # 与上相同
$ git diff -3 file.txt # 与暂存3进行比较
$ git diff --theirs file.txt # 与上相同.
还有,git log和gitk命令也为合并操作提供了特别的协助:
$ git log --merge
$ gitk --merge
这会显示所有那些只在HEAD或者只在MERGE_HEAD中存在的提交,还有那些更新(touch)了未合并文件的提交.
你也可以使用git mergetool, 它允许你使用外部工具如emacs或kdiff3去合并文件.
每次你解决冲突之后, 应该更新索引:
$ git add file.txt
完成索引更新之后, git-diff(缺省地)不再显示那个文件的差异,所以那个文件的不同暂存版本会被"折叠"起来.
六、多路合并
你可以一次合并多个头, 只需简单地把它们作为git merge的参数列出.例如,
$ git merge scott/master rick/master tom/master
相当于:
$ git merge scott/master
$ git merge rick/master
$ git merge tom/master
七、子树
有时会出现你想在自己项目中引入其他独立开发项目的内容的情况. 在没有路径冲突的前提下, 你只需要简单地从其他项目拉取内容即可.
如果有冲突的文件, 那么就会出现问题.可能的例子包括Makefile和其他一些标准文件名.你可以选择合并这些冲突的文件,但是更多的情况是你不愿意把它们合并.一个更好解决方案是把外部项目作为一个子目录进行合并.这种情况不被递归合并策略所支持,所以简单的拉取是无用的.
在这种情况下, 你需要的是子树合并策略.
这下面例子中, 我们设定你有一个仓库位于/path/to/B (如果你需要的话,也可以是一个URL).你想要合并那个仓库的master分支到你当前仓库的dir-B子目录下.
下面就是你所需要的命令序列:
$ git remote add -f Bproject /path/to/B (1)
$ git merge -s ours --no-commit Bproject/master (2)
$ git read-tree --prefix=dir-B/ -u Bproject/master (3)
$ git commit -m "Merge B project as our subdirectory" (4)
$ git pull -s subtree Bproject master (5)
子树合并的好处就是它并没有给你仓库的用户增加太多的管理负担. 它兼容于较老(版本号小于1.5.2)的客户端,克隆完成之后马上可以得到代码.
然而, 如果你使用子模块(submodule),你可以选择不传输这些子模块对象.这可能在子树合并过程中造成问题.
译者注: submodule是Git的另一种将别的仓库嵌入到本地仓库方法.
另外, 若你需要修改内嵌外部项目的内容,使用子模块方式可以更容易地提交你的修改
git push -u origin v1.0.0 -f强制更新
编辑注释 git commit --amend
有个疑问?
Git 多个分支后,本地如何选择那个分支的代码进行使用?
比如我现在有两个分支,master 和 1.0.0,我想要工1.0.0的代码,如何取得?
在git中,我们其实可以通过^和~来定位某个具体的commit,而不用每次都去敲繁琐的hash值。为了便于大家理解,先把结论放在前面:
1.“^”代表父提交,当一个提交有多个父提交时,可以通过在”^”后面跟上一个数字,表示第几个父提交,”^”相当于”^1”.
2. ~<n>相当于连续的<n>个”^”.
3. checkout只会移动HEAD指针,reset会改变HEAD的引用值。
这三大部分中:
working tree:就是你所工作在的目录,每当你在代码中进行了修改,working tree的状态就改变了。
index file:是索引文件,它是连接working tree和commit的桥梁,每当我们使用git-add命令来登记后,index file的内容就改变了,此时index file就和working tree同步了。
commit:是最后的阶段,只有commit了,我们的代码才真正进入了git仓库。我们使用git-commit就是将index file里的内容提交到commit中。
总结一下:
git diff:是查看working tree与index file的差别的。
git diff --cached:是查看index file与commit的差别的。
git diff HEAD:是查看working tree和commit的差别的。(你一定没有忘记,HEAD代表的是最近的一次commit的信息)
git diff HEAD
上面这条命令会显示你工作目录与上次提交时之间的所有差别,这条命令所显示的 内容都会在执行"git commit -a"命令时被提交。
git diff HEAD^
上面这条命令会显示你工作目录与上上次提交时之间的所有差别
但是为什么不能用git diff HEAD^2以上的呢????
git diff --stat
如果不是查看每个文件的详细差别,而是统计一下有哪些文件被改动,有多少行被改 动,就可以使用‘--stat' 参数
查看HEAD和引用的值
我们可以通过命令来查看HEAD和引用的值,也可以通过当前仓库下的.git目录去访问。当前分支为master时,我们查看HEAD的值,命令如下:
$ cat .git/HEAD ref: refs/heads/master
然后,我们可以查看master引用的值
$ cat .git/refs/heads/master3b0370b....... # hash code
Git检出制定版本
问题:Git采用分布式版本管理,不需要像SVN每一个分支都是一个完整项目。当我们需要找出某个版本或者某次提交时的版本时,应该怎么操作?
解决:这里列举一个实例,本地没有版本需要从服务器检出指定某次提交是的版本
本示例就拿git@china做演示
第一步:先从服务器上找到版本提交日志 具体到哪一天 哪一次提交
左边的字符串就是你提交那次版本
第二步:
本地创建一个文件夹 clone出你的项目
第三部:通过IDE开发工具打开,便发现是你所要的版本,很简单吧,开始习惯使用git吧
今天碰到一个问题,git reset HEAR^后,不知道如何处理了。最后git pull居然冲突,最后撤销本地修改git reset hard还是不行,最后网上搜了下
解决git冲突造成的Please move or remove them before you can merge
git clean -d -fx ""
其中
x -----删除忽略文件已经对git来说不识别的文件
d -----删除未被添加到git的路径中的文件
f -----强制运行
不知道会产生什么影响
其实有些文件未被加入git的话,可以用git status来查看。然后采取措施。
获取远程新分支,如果用命令行,运行 git fetch,可以将远程分支信息获取到本地,再运行git checkout -b local-branchname origin/remote_branchname
Get fetch 获取所有的远程分支到本地,然后通过git branch -a可以查看到所有的远程分支
获取远程分支到本地
Git fetch origin branch
查看的方法是 origin/branch,,比如对比远程分支与本地分支的区别
可以git diff branch_local orgin/branch
上面的操作也可这也
git fetch origin master:tmp创建一个临时分支
git diff tmp 查看与本地分支的区别
git merge tmp 合并到本地分支
查看两个版本的区别
Git log -p v1.0.0.. Origin/v2.0.0但不清楚能看出哪些不同
git log --oneline B ^A 可以列出B分支有而A分支没有的提交
git log --oneline A ^B 可以列出A分支有而B分支没有的提交
git log dev...master 不知道谁提交的多谁提交的少,单纯想知道有什么不一样:
将master分支合并到feature分支最简单的办法就是用下面这些命令:
git checkout feature
git merge master
或者,你也可以把它们压缩在一行里。
git merge master feature
Your local changes to the following files would be overwritten by merge
error: Your local changes to the following files would be overwritten by merge:
protected/config/main.php
Please, commit your changes or stash them before you can merge.
参考http://blog.youkuaiyun.com/zwhfyy/article/details/8625228
如果希望保留生产服务器上所做的改动,仅仅并入新配置项,处理方法如下:
git stash
git pull
git stash pop
然后可以使用git diff -w +文件名 来确认代码自动合并的情况.
反过来,如果希望用代码库中的文件完全覆盖本地工作版本.方法如下:
git reset --hard
git pull
其中git reset是针对版本,如果想针对文件回退本地修改,使用
untracked working tree file
参考:http://blog.youkuaiyun.com/sheismylife/article/details/7204345
编写脚本自动编译并部署时的注意
如果想在C2上编写脚本自动从S1上获取最新代码时,要注意:
1.首先之前产生的公钥不能设密码,否则每次git pull的时候都会要求输入密码。
2.不要将项目中的编译中间文件提交到S1上,比如CMake工程里面的build目录的文件,Maven工程里面的target目录里面的文件。否则下次在C2等客户端用git pull会报类似于这样的错误:
error: Untracked working tree file 'public/images/icon.gif' would be overwritten by merge.
需要执行下面的命令才能修复:
git reset --hard HEAD
git clean -f -d
git pull
git reset soft,hard,mixed之区别深解
时间:2015-05-19 00:28:42 阅读:8288 评论:0 收藏:0 [点我收藏+]
标签:class style log com 使用 src http it 文件
GIT reset命令,似乎让人很迷惑,以至于误解,误用。但是事实上不应该如此难以理解,只要你理解到这个命令究竟在干什么。
首先我们来看几个术语
HEAD
这是当前分支版本顶端的别名,也就是在当前分支你最近的一个提交
Index
index也被称为staging area,是指一整套即将被下一个提交的文件集合。他也是将成为HEAD的父亲的那个commit
Working Copy
working copy代表你正在工作的那个文件集
Flow
当你第一次checkout一个分支,HEAD就指向当前分支的最近一个commit。在HEAD中的文件集(实际上他们从技术上不是文件,他们是blobs(一团),但是为了讨论的方便我们就简化认为他们就是一些文件)和在index中的文件集是相同的,在working copy的文件集和HEAD,INDEX中的文件集是完全相同的。所有三者(HEAD,INDEX(STAGING),WORKING COPY)都是相同的状态,GIT很happy。
当你对一个文件执行一次修改,Git感知到了这个修改,并且说:“嘿,文件已经变更了!你的working copy不再和index,head相同!”,随后GIT标记这个文件是修改过的。
然后,当你执行一个git add,它就stages the file in the index,并且GIT说:“嘿,OK,现在你的working copy和index区是相同的,但是他们和HEAD区是不同的!”
当你执行一个git commit,GIT就创建一个新的commit,随后HEAD就指向这个新的commit,而index,working copy的状态和HEAD就又完全匹配相同了,GIT又一次HAPPY了。
Reset
如果你仔细研究reset命令本身就知道,它本身做的事情就是重置HEAD(当前分支的版本顶端)到另外一个commit。假设我们有一个分支(名称本身无所谓,所以我们就简单称为"super-duper-feature”分支吧),图形化表示如下:
如果我们执行:
git reset HEAD
任何事情都不会发生,这是因为我们告诉GIT重置这个分支到HEAD,而这个正是它现在所在的位置。
git reset HEAD~1
当我们再执行上面的命令时(HEAD~1是“the commit right before HEAD”的别名,或者说:put differently "HEAD‘s parent"),我们的分支将会如下所示
如果我们执行git reset HEAD~2,则意味着将HEAD从顶端的commit往下移动两个更早的commit。
Parameters
soft
--soft参数告诉Git重置HEAD到另外一个commit,但也到此为止。如果你指定--soft参数,Git将停止在那里而什么也不会根本变化。这意味着index,working copy都不会做任何变化,所有的在original HEAD和你重置到的那个commit之间的所有变更集仍然在stage(index)区域中。
2.hard
--hard参数将会blow out everything.它将重置HEAD返回到另外一个commit(取决于~12的参数),重置index以便反映HEAD的变化,并且重置working copy也使得其完全匹配起来。这是一个比较危险的动作,具有破坏性,数据因此可能会丢失!如果真是发生了数据丢失又希望找回来,那么只有使用:git reflog命令了
3.mixed(default)
--mixed是reset的默认参数,也就是当你不指定任何参数时的参数。它将重置HEAD到另外一个commit,并且重置index以便和HEAD比配,但是也到此为止。working copy不会被更改。所以所有从original HEAD到你重置到的那个commit之间的所有变更仍然保存在working copy中,被标示为已变更,但是并未staged的状态
git reset soft,hard,mixed之区别深解
最近在使用Git管理项目工程的时候,遇到了很多问题,也学习到了很多关于Git常见使用的技巧,下面就其中关于Git Stash的用法和大家分享下。
首先,简单介绍下Git Stash命令的用法,详细的用法在man文档中有相关介绍,下面我来说明常见的使用。
git stash: 备份当前的工作区的内容,从最近的一次提交中读取相关内容,让工作区保证和上次提交的内容一致。同时,将当前的工作区内容保存到Git栈中。
git stash pop: 从Git栈中读取最近一次保存的内容,恢复工作区的相关内容。由于可能存在多个Stash的内容,所以用栈来管理,pop会从最近的一个stash中读取内容并恢复。
git stash list: 显示Git栈内的所有备份,可以利用这个列表来决定从那个地方恢复。
git stash clear: 清空Git栈。此时使用gitg等图形化工具会发现,原来stash的哪些节点都消失了。
关于Git Stash的详细解释,适用场合,这里做一个说明:
使用git的时候,我们往往使用branch解决任务切换问题,例如,我们往往会建一个自己的分支去修改和调试代码, 如果别人或者自己发现原有的分支上有个不得不修改的bug,我们往往会把完成一半的代码 commit提交到本地仓库,然后切换分支去修改bug,改好之后再切换回来。这样的话往往log上会有大量不必要的记录。其实如果我们不想提交完成一半或者不完善的代码,但是却不得不去修改一个紧急Bug,那么使用'git stash'就可以将你当前未提交到本地(和服务器)的代码推入到Git的栈中,这时候你的工作区间和上一次提交的内容是完全一样的,所以你可以放心的修 Bug,等到修完Bug,提交到服务器上后,再使用'git stash apply'将以前一半的工作应用回来。也许有的人会说,那我可不可以多次将未提交的代码压入到栈中?答案是可以的。当你多次使用'git stash'命令后,你的栈里将充满了未提交的代码,这时候你会对将哪个版本应用回来有些困惑,'git stash list'命令可以将当前的Git栈信息打印出来,你只需要将找到对应的版本号,例如使用'git stash apply stash@{1}'就可以将你指定版本号为stash@{1}的工作取出来,当你将所有的栈都应用回来的时候,可以使用'git stash clear'来将栈清空。
在这里顺便提下git format-patch -n , n是具体某个数字, 例如 'git format-patch -1' 这时便会根据log生成一个对应的补丁,如果 'git format-patch -2' 那么便会生成2个补丁,当然前提是你的log上有至少有两个记录。
看过上面的信息,就可以知道使用场合了:当前工作区内容已被修改,但是并未完成。这时Boss来了,说前面的分支上面有一个Bug,需要立即修复。可是我又不想提交目前的修改,因为修改没有完成。但是,不提交的话,又没有办法checkout到前面的分支。此时用Git Stash就相当于备份工作区了。然后在Checkout过去修改,就能够达到保存当前工作区,并及时恢复的作用。
下面,将我使用过程中遇到的一个问题和大家分享:
首先,在Git Stash之后,提交图如下所示:
从图中可以看到,develop和newdevelop是在同一个分支上,因为分支newdevelop是在develop分支的基础上开发的。想加入一个新的特性,所以就开了newdevelop分支,然后就在上面加东西,加特性,该代码。这个时候工作的内容已经变化了,但是develop和newdevelop都是指向同一个提交的,因为newdevelop上面还木有提交。
这个时候,Boss来了,说develop上面有个Bug,赶快改一下,手头的工作先放放,稳定版本不能有缺陷。没办法,当前正在newdevelop上搞的high呢,就Git Stash一下。所以会看到上面有两个节点,红色以及上面一个。就是stash之后的结果,注意是在newdevelop上面进行的stash。
正如前面所说,stash会暂存当前的工作区内容,然后将工作区内容保持和上次提交相同,此时内容都是上面8a32那个提交的内容。从终端中查看相应的信息内容,如下:
印证了签名的说法,newdevelop是有修改,modified,然后stash之后,工作区是最近一次提交,此时newdevelop和develop都是相同的,所以再git status查看发现,都一样,nothing to commit.
然后Stash完成之后,就要Fix Bug了。为此,回到develop分支上进行修复,然后提交,完成后的提交图如下所示:
从途中可以看到,newdevelop还是在下面,因为指向的是老的那个8a32的commit。新的develop由于修复了Bug,所以产生一个新提交。
然后在develop上面修复了Bug之后,在回到newdevelop上面进行一个新的特性的继续编码,此时checkout回去的时候,没有神马内容可以提交,因为都存在Stash中了,没有任何修改。如上图。
那么,恢复工作区内容吧。于是git stash pop(注意这里由于只Stash了一次所以使用pop,具体你存放了多少,要恢复哪一个要自己清楚,否则会出错!)
恢复之后,从上图中可以看到,此时再git status就会发现文件有修改,说明恢复过来了。然后就继续编码,提交一个稳定的新特性版本,如下图,产生的新提交为0906.
然后再查看提交图,会发现,stash pop之后,对应的存放的stash被清空掉了,提交图中,newdevelop上面对应一个新的提交。并且在develop上面。分支的develop那个红色,即为前面修复Bug的那个提交。
总结起来:
操作很简单,但是头脑要清楚。要在哪个分支上修复Bug,要暂存哪个地方的内容,之后修复完了在那个地方提交,然后要到哪个分支上面恢复工作区,都是需要注意的,否则,很容易造成提交图混乱。只有弄清楚了工作流程,才不容易出错,才能保证很高的工作效率。
最后一句:Git是神器,就要看你如何驾驭它了。