一、
1、git status查看文件提交状态
该分支本地代码未提交commit
如果新增文件
如果已经提交了 但还没有push到远程
该分支本地代码和远程代码一致
2、日志显示 tip:空格向下翻页,b向上翻页,q退出
git log:查看历史提交
git log --pretty=oneline:以漂亮的一行显示,包含全部哈希索引值
git log --oneline:以简洁的一行显示,包含简洁哈希索引值
git reflog:以简洁的一行显示,包含简洁哈希索引值,同时显示移动到某个历史版本所需的步数
3.版本控制
git reset --hard 简洁/完整哈希索引值:回到指定哈希值所对应的版本
git reset --hard HEAD:强制工作区、暂存区、本地库为当前HEAD指针所在的版本
git reset --hard HEAD^:后退一个版本
tip:一个^表示回退一个版本
git reset --hard HEAD~1:后退一个版本
tip:波浪线~后面的数字表示后退几个版本
4.比较差异
git diff:比较工作区和暂存区的所有文件差异
git diff :比较工作区和暂存区的指定文件的差异
git diff HEAD|HEAD^|HEAD~|哈希索引值 :比较工作区跟本地库的某个版本的指定文件的差异
5.分支操作
git branch -v:查看所有分支
git branch -d :删除本地分支
git branch :新建分支
git checkout :切换分支
git merge :合并分支
tip:如master分支合并 hot_fix分支,那么当前必须处于master分支上,然后执行 git merge hot_fix 命令
tip2:合并出现冲突
①删除git自动标记符号,如<<<<<<< HEAD、>>>>>>>等
②修改到满意后,保存退出
③git add
④git commit -m "日志信息",此时后面不要带文件名
二、本地库跟远程库交互:
git clone :克隆远程库
功能:①完整的克隆远程库为本地库,②为本地库新建origin别名,③初始化本地库
git remote -v:查看远程库地址别名
git remote add :新建远程库地址别名
git remote rm :删除本地中远程库别名
git push :本地库某个分支推送到远程库,分支必须指定
git pull :把远程库的修改拉取到本地
tip:该命令包括git fetch,git merge
git fetch :抓取远程库的指定分支到本地,但没有合并
git merge :将抓取下来的远程的分支,跟当前所在分支进行合并
git fork:复制远程库
tip:一般是外面团队的开发人员fork本团队项目,然后进行开发,之后外面团队发起pull request,然后本团队进行审核,如无问题本团队进行merge(合并)到团队自己的远程库,整个流程就是本团队跟外面团队的协同开发流程,Linux的团队开发成员即为这种工作方式。
三、什么是tag
tag是git版本库的一个标记,指向某个commit的指针。
tag主要用于发布版本的管理,一个版本发布之后,我们可以为git打上 v.1.0.1 v.1.0.2 ...这样的标签。
tag感觉跟branch有点相似,但是本质上和分工上是不同的:
tag 对应某次commit, 是一个点,是不可移动的。
branch 对应一系列commit,是很多点连成的一根线,有一个HEAD 指针,是可以依靠 HEAD 指针移动的。
所以,两者的区别决定了使用方式,改动代码用 branch ,不改动只查看用 tag。
tag 和 branch 的相互配合使用,有时候起到非常方便的效果,例如:已经发布了 v1.0 v2.0 v3.0 三个版本,这个时候,我突然想不改现有代码的前提下,在 v2.0 的基础上加个新功能,作为 v4.0 发布。就可以检出 v2.0 的代码作为一个 branch ,然后作为开发分支。
1.创建tag:
创建 tag 是基于本地分支的 commit,而且与分支的推送是两回事,就是说分支已经推送到远程了,但是你的 tag 并没有,如果把 tag 推送到远程分支上,需要另外执行 tag 的推送命令。
git tag //创建本地tag
git push origin //推送到远程仓库
若存在很多未推送的本地标签,你想一次全部推送的话:
git push origin --tags
以上是基于本地当前分支的最后的一个commit 创建的 tag ,但是如果不想以最后一个,只想以某一个特定的提交为tag ,也是可以的,只要你知道commit 的id。
git log --pretty=oneline //查看当前分支的提交历史 里面包含 commit id
git tag -a
2.查看标签
查看本地某个 tag 的详细信息:
git show
查看本地所有 tag:
git tag 或者 git tag -l
查看远程所有 tag:
git ls-remote --tags origin
3.删除标签
本地 tag 的删除:
git tag -d
远程 tag 的删除:
git push origin :
4.检出标签
git checkout -b
因为 tag 本身指向的就是一个 commit,所以和根据commit id 检出分支是一个道理。
但是需要特别说明的是,如果我们想要修改 tag检出代码分支,那么虽然分支中的代码改变了,但是 tag标记的 commit还是同一个,标记的代码是不会变的,这个要格外的注意。
其它
命令git tag -a -m "XXX..." 可以指定标签信息。
命令git tag -a v0.1.0 -m "release 0.1.0 version" 创建附注标签。
命令git checkout [tagname] 切换标签。
五、Rebase
假设你现在基于远程分支"origin",创建一个叫"mywork"的分支。
$ git checkout -b mywork origin
现在我们在这个分支做一些修改,然后生成两个提交(commit).
$ vi file.txt $ git commit $ vi otherfile.txt $ git commit ...
但是与此同时,有些人也在"origin"分支上做了一些修改并且做了提交了. 这就意味着"origin"和"mywork"这两个分支各自"前进"了,它们之间"分叉"了。
在这里,你可以用"pull"命令把"origin"分支上的修改拉下来并且和你的修改合并;结果看起来就像一个新的"合并的提交"(merge commit):
但是,如果你想让"mywork"分支历史看起来像没有经过任何合并一样,你也许可以用 git rebase:
$ git checkout mywork $ git rebase origin
这些命令会把你的"mywork"分支里的每个提交(commit)取消掉,并且把它们临时 保存为补丁(patch)(这些补丁放到".git/rebase"目录中),然后把"mywork"分支更新 到最新的"origin"分支,最后把保存的这些补丁应用到"mywork"分支上。
当'mywork'分支更新之后,它会指向这些新创建的提交(commit),而那些老的提交会被丢弃。如果运行垃圾收集命令(pruning garbage collection), 这些被丢弃的提交就会删除. (请查看 git gc)
现在我们可以看一下用合并(merge)和用rebase所产生的历史的区别:
在rebase的过程中,也许会出现冲突(conflict). 在这种情况,Git会停止rebase并会让你去解决 冲突;在解决完冲突后,用"git-add"命令去更新这些内容的索引(index), 然后,你无需执行 git-commit,只要执行:
$ git rebase --continue
这样git会继续应用(apply)余下的补丁。
在任何时候,你可以用--abort参数来终止rebase的行动,并且"mywork" 分支会回到rebase开始前的状态。
$ git rebase --abort
六、restash
今天在看一个bug,之前一个分支的版本是正常的,在新的分支上上加了很多日志没找到原因,希望回溯到之前的版本,确定下从哪个提交引入的问题,但是还不想把现在的修改提交,也不希望在Git上看到当前修改的版本(带有大量日志和调试信息)。因此呢,查查Git有没有提供类似功能,就找到了git stash的命令。
综合下网上的介绍和资料,git stash(git储藏)可用于以下情形:
- 发现有一个类是多余的,想删掉它又担心以后需要查看它的代码,想保存它但又不想增加一个脏的提交。这时就可以考虑git stash。
- 使用git的时候,我们往往使用分支(branch)解决任务切换问题,例如,我们往往会建一个自己的分支去修改和调试代码, 如果别人或者自己发现原有的分支上有个不得不修改的bug,我们往往会把完成一半的代码commit提交到本地仓库,然后切换分支去修改bug,改好之后再切换回来。这样的话往往log上会有大量不必要的记录。其实如果我们不想提交完成一半或者不完善的代码,但是却不得不去修改一个紧急Bug,那么使用git stash就可以将你当前未提交到本地(和服务器)的代码推入到Git的栈中,这时候你的工作区间和上一次提交的内容是完全一样的,所以你可以放心的修Bug,等到修完Bug,提交到服务器上后,再使用git stash apply将以前一半的工作应用回来。
- 经常有这样的事情发生,当你正在进行项目中某一部分的工作,里面的东西处于一个比较杂乱的状态,而你想转到其他分支上进行一些工作。问题是,你不想提交进行了一半的工作,否则以后你无法回到这个工作点。解决这个问题的办法就是git stash命令。储藏(stash)可以获取你工作目录的中间状态——也就是你修改过的被追踪的文件和暂存的变更——并将它保存到一个未完结变更的堆栈中,随时可以重新应用。
git stash用法
1. stash当前修改
git stash会把所有未提交的修改(包括暂存的和非暂存的)都保存起来,用于后续恢复当前工作目录。
比如下面的中间状态,通过git stash命令推送一个新的储藏,当前的工作目录就干净了。
$ git status On branch master Changes to be committed: new file: style.css Changes not staged for commit: modified: index.html $ git stash Saved working directoryandindex state WIP onmaster: 5002d47 our new homepageHEADisnowat 5002d47 our new homepage $ git statusOn branch masternothingtocommit, working tree clean
需要说明一点,stash是本地的,不会通过git push命令上传到git server上。
实际应用中推荐给每个stash加一个message,用于记录版本,使用git stash save取代git stash命令。示例如下:
$ git stash save "test-cmd-stash"Saved working directory and index state On autoswitch: test-cmd-stash HEAD 现在位于 296e8d4 remove unnecessary postion reset in onResume function $ git stash list stash@{0}: On autoswitch: test-cmd-stash
2. 重新应用缓存的stash
可以通过git stash pop命令恢复之前缓存的工作目录,输出如下:
$ git status On branch master nothing to commit, working tree clean $ git stash popOn branch masterChanges to be committed: newfile: style.css Changes not staged forcommit: modified: index.html Dropped refs/stash@{0} (32b3aa1d185dfe6d57b3c3cc3b32cbf3e380cc6a)
这个指令将缓存堆栈中的第一个stash删除,并将对应修改应用到当前的工作目录下。
你也可以使用git stash apply命令,将缓存堆栈中的stash多次应用到工作目录中,但并不删除stash拷贝。命令输出如下:
$ git stash applyOn branch master Changes to be committed: new file: style.css Changes not staged for commit: modified: index.html
3. 查看现有stash
可以使用git stash list命令,一个典型的输出如下:
$ git stash list stash@{0}: WIP on master: 049d078 added the index file stash@{1}: WIP on master: c264051 Revert "added file_size"stash@{2}: WIP on master: 21d80a5 added number to log
在使用git stash apply命令时可以通过名字指定使用哪个stash,默认使用最近的stash(即stash@{0})。
4. 移除stash
可以使用git stash drop命令,后面可以跟着stash名字。下面是一个示例:
$ git stash list stash@{0}: WIP on master: 049d078 added the index file stash@{1}: WIP on master: c264051 Revert "added file_size"stash@{2}: WIP on master: 21d80a5 added number to log$ git stash drop stash@{0} Dropped stash@{0} (364e91f3f268f0900bc3ee613f9f733e82aaed43)
或者使用git stash clear命令,删除所有缓存的stash。
5. 查看指定stash的diff
可以使用git stash show命令,后面可以跟着stash名字。示例如下:
$ git stash show index.html | 1 + style.css | 3 +++ 2 files changed, 4 insertions(+)
在该命令后面添加-p或--patch可以查看特定stash的全部diff,如下:
$ git stash show -p diff --git a/style.css b/style.css new file mode 100644 index 0000000..d92368b--- /dev/null+++ b/style.css@@ -0,0 +1,3 @@+* {+ text-decoration: blink;+}diff --git a/index.html b/index.html index 9daeafb..ebdcbd2 100644--- a/index.html+++ b/index.html@@ -1 +1,2 @@+
6. 从stash创建分支
如果你储藏了一些工作,暂时不去理会,然后继续在你储藏工作的分支上工作,你在重新应用工作时可能会碰到一些问题。如果尝试应用的变更是针对一个你那之后修改过的文件,你会碰到一个归并冲突并且必须去化解它。如果你想用更方便的方法来重新检验你储藏的变更,你可以运行 git stash branch,这会创建一个新的分支,检出你储藏工作时的所处的提交,重新应用你的工作,如果成功,将会丢弃储藏。
$ git stash branch testchanges Switched to a new branch "testchanges"# On branch testchanges# Changes to be committed:# (use "git reset HEAD ..." to unstage)## modified: index.html## Changes not staged for commit:# (use "git add ..." to update what will be committed)## modified: lib/simplegit.rb#Dropped refs/stash@{0} (f0dfc4d5dc332d1cee34a634182e168c4efc3359)
这是一个很棒的捷径来恢复储藏的工作然后在新的分支上继续当时的工作。
7. 暂存未跟踪或忽略的文件
默认情况下,git stash会缓存下列文件:
- 添加到暂存区的修改(staged changes)
- Git跟踪的但并未添加到暂存区的修改(unstaged changes)
但不会缓存一下文件:
- 在工作目录中新的文件(untracked files)
- 被忽略的文件(ignored files)
git stash命令提供了参数用于缓存上面两种类型的文件。使用-u或者--include-untracked可以stash untracked文件。使用-a或者--all命令可以stash当前目录下的所有修改。
至于git stash的其他命令建议参考Git manual。
8、
场景如下,你正在开发需求1时,突然线上发现了一个bug,需要立即修复。需求1的代码因为不完善,也没经过测试,所以你希望针对需求1所做的修改先暂时隐藏,这样就可以使用 stash功能了。
VCS-->git -->stash
这个时候针对需求1做的修改都会隐藏掉。现在假设你处理bug完毕。需要继续开发需求,现在需要unstash
VCS-->git-->Unstash,选中你刚刚的stash,选中Pop stash。点击pop stash即可。如下图:
但是我这里遇到个问题,屏幕右下角有如下提示:
点击View them,发现是.DS_store 文件,这个我已经在.gitignore中声明忽略该文件了。所以我的localChanges中并没有该文件。
没办法,只有先修改.gitignore,不忽略.DS_store.然后执行git status 能看到两个文件被修改了
然后执行git checkout -- ../.DS_Store 即回滚 .DS_store。然后重新unstash,ok。
然后也需要回滚.gitignore