1、GIT 本地相关指令
GIT架构图
工作区、暂存区理解
git add
git commit
暂存区可以理解为本地的svn客户端的工作区(git add的); git commit可以理解为本地版本库,即本地的svn服务器。
工作区即是本地磁盘。
git checkout – file 舍弃工作区文件的更改
前提条件是未git add的文件,
例如1:
git checkout -- readme.txt
例如2:
`rm test.txt //可通过 git checkout -- file恢复`
git reset HEAD <file> 将文件从暂存区移除
前提条件是已经git add 或者 git rm, 但未git commit的文件,如果已经commit了,就需要git revert commitID 指令了。
例如:
git reset HEAD readme.txt
git rm
git rm test.txt //与 git add 相对应, 可通过 git reset HEAD file 恢复
git commit -m “remove test.txt” //可通过 git reset commit_id 恢复 、git revert commitID
git log
git log --oneline
git log --pretty=oneline
git log --pretty=oneline --abbrev-commit
git log --graph --pretty=oneline --abbrev-commit
git reflog
git reset 扩展
–soft 与 --hard 区别
git reset –-soft:回退到某个版本,只回退了commit的信息,暂存区的修改还存在,如果还要提交,直接commit即可;
git reset -–hard:彻底回退到某个版本,本地的源码也会变为上一个版本的内容,工作区、暂存区的更改都将不存在。
应用场景:
有时候,进行了错误的提交,但是还没有push到远程分支,想要撤销本次提交,可以使用git reset –-soft/hard命令。
git reset --hard HEAD^
git reset --hard HEAD^^
git reset --hard HEAD~100
git log
git reset --hard commit_id
例如:
git reset --hard 1094a
git reflog
现在,你回退到了某个版本,关掉了电脑,第二天早上就后悔了,想恢复到新版本怎么办?找不到新版本的commit id怎么办?
在Git中,总是有后悔药可以吃的。当你用$ git reset --hard HEAD^回退到add distributed版本时,再想恢复到append GPL,就必须找到append GPL的commit id。Git提供了一个命令git reflog用来记录你的每一次命令:
$ git reflog
e475afc HEAD@{1}: reset: moving to HEAD^
1094adb (HEAD -> master) HEAD@{2}: commit: append GPL
e475afc HEAD@{3}: commit: add distributed
eaadf4e HEAD@{4}: commit (initial): wrote a readme file
git revert commitID
Revert撤销一个提交的同时会创建一个新的提交。这是一个安全的方法,因为它不会重写提交历史。比如,下面的命令会找出倒数第二个提交,然后创建一个新的提交来撤销这些更改,然后把这个提交加入项目中。
git revert HEAD~2
git diff 比较工作区和暂存区
git diff 比较所有文件的差异
git diff 比较指定文件的差异
特殊:
git diff HEAD|HEAD^|HEAD~|哈希索引值 比较工作区跟本地库的某个版本的指定文件的差异
2、GIT 远端相关指令
git clone
Git支持多种协议,默认的git://使用ssh,但也可以使用https等其他协议。使用https除了速度慢以外,还有个最大的麻烦是每次推送都必须输入口令,但是在某些只开放http端口的公司内部就无法使用ssh协议而只能用https。
当你从远程仓库克隆时,实际上Git自动把本地的master分支和远程的master分支对应起来了,并且,远程仓库的默认名称是origin。
git remote
要查看远程库的信息,用git remote:
$ git remote
origin
$ git remote -v
origin git@github.com:michaelliao/learngit.git (fetch)
origin git@github.com:michaelliao/learngit.git (push)
git remote add <别名> <远程库地址> 新建远程库地址别名
git remote rm <别名> 删除本地中远程库别名
git fetch
从远端获取关于origin的所有分支日志信息等
git fetch -p origin 清除远程分支的本地缓存
git pull
把远程库的修改拉取到本地:
git pull 注意: 该命令包括git fetch,git merge
git pull失败,提示未关联,需要执行如下语句,进行关联:
git branch --set-upstream-to=origin/remote_branch your_branch
git pull --rebase 注意: 该命令包括 git fetch, git rebase
git push
仅记:push之前需要先pull, 防止其他人已经在你之前进行了push操作。
git push -u origin master
我们第一次推送master分支时,加上了-u参数,Git不但会把本地的master分支内容推送的远程新的master分支,还会把本地的master分支和远程的master分支关联起来,在以后的推送或者拉取时就可以简化命令。
此后,每次本地提交后,就可以使用命令git push origin master推送最新修改;如果要推送其他分支,比如dev,就改成:git push origin dev
git push origin master -f
git branch
查看本地分支
git branch -a 查看本地分支 和 远程分支信息 可配合 git branch -a | grep lifs 使用
创建分支
git branch dev 仅是创建了分支,但是并未切换。
删除分支
git branch -d dev merge之后可用此指令删除本地分支
git branch -D dev 要丢弃一个没有被合并过的分支时,通过 -D 进行强制删除
git push origin --delete dev 远程分支名称
git checkout
切换分支
git checkout dev
创建分支并切换
git checkout -b dev 等效于: git branch dev; git checkout dev; 等效于 git switch -c dev
从远处拉取指定分支
git checkout -b branch-name origin/branch-name,本地和远程分支的名称最好一致;
git checkout -b dev origin/dev
git merge
git merge branch_name 用于合并指定分支branch_name 到当前分支。
git merge --no-ff branch_name -m “merge with no-ff” 非Fast forward快进模式进行merge。
merge时有冲突, 解决冲突后还是需要 git add; git commit;
git cherry-pick
git cherry-pick commit_id 这个commit_id是其他分支上提交时的日志commit_id
----------------------
Git从1.7.2版本开始支持批量cherry-pick,就是一次可以cherry-pick一个区间的commit。
git cherry-pick …
git cherry-pick ^…
前者表示把到之间(左开右闭,不包含start-commit-id)的提交cherry-pick到当前分支;
后者有"^"标志的表示把到之间(闭区间,包含start-commit-id)的提交cherry-pick到当前分支。
----------------------
如果不想git cherry-pick自动进行提交,则加参数-n即可。
git cherry-pick -n
当使用git cherry-pick发生冲突后,将会出现如下信息:
这时如果要继续cherry-pick,则首先需要解决冲突,通过git add .将文件标记为已解决,然后可以使用git cherry-pick --continue命令,继续进行cherry-pick操作。
如果要中断这次cherry-pick,则使用git cherry-pick --quit,这种情况下当前分支中未冲突的内容状态将为modified,
如果要取消这次cherry-pick,则使用git cherry-pick --abort,这种情况下当前分支恢复到cherry-pick前的状态,没有改变。
git stash
git stash list
git stash apply 恢复后,stash内容并不删除; 需要用git stash drop来删除;
例如: git stash apply stash@{0}
git stash pop 恢复的同时把stash内容也删了:
git rebase
应用:
在差分分支时的两种办法: 1、merge;2、rebase
区别:
rebase相当于以rebase的版本重新创建分支, 然后在将自己的每次修改分别在该分支上逐次提交。
所以log的结果就是,自己的每次修改都会在rebase版本的log之上。
注意: rebase慎用, 因为会导致log顺序变化,也不能回退至rebase之前,除非重新rebase,但是log顺序已经无法更改。
merge相当于真正的差分, 将其他分支上的修改,依照提交顺序差分到自己分支上来, log是依照提交顺序排列的, 所以该中差分比较完美, 建议使用此方法。
另:建议使用git merge命令进行差分, 之后再用图形界面工具软件处理冲突。因为通过图形界面软件工具进行merge,在中途即让你处理冲突文件, 而此时处理的冲突文件可能不是最终的版本, 而通过指令merge不会让你中途进行处理, 而是在merge最后让你进行处理。 不清楚它俩的本质是否一样,但是还是通过git merge指令进行吧,毕竟中途不会让你处理冲突。
------------------------------------------------------------------------------------------------------------------------------------
个人实践总结:
git rebase 后, 马上进行 git log 可以发现如预期一样, 但是不能git push,因为此时本地分支已经跟远端分支有冲突了(远端分支之前已经push过了,想想这个分支如果是还有其他同事在使用,git不允许这么做),git status提示进行git pull,之后在git push,但是此时git push后在git log,发现已经跟预期的不一样了。
PS:pro git 上的一句话:
“永远不要衍合那些已经推送到公共仓库的更新。
如果你遵循这条金科玉律,就不会出差错。否则,人民群众会仇恨你,你的朋友和家人也
会嘲笑你,唾弃你。” 看到这句话你大概就知道该怎么用了。至少不会用坏。
所以 在 git rebase后, 不要进行git pull,
处理办法:
1、在git push 时加入参数 -f(–force)即可 。
2、删除远端分支,然后进行git push。
------------------------------------------------------------------------------------------------------------------------------------
git rebase 真正的使用方法,应该就是不用Git push 到 Dev上;git rebase后,本地已经如预期一样了, 此时直接到主分支上进行git merge,然后删除dev分支。
所以Git rebase的使用时机就是,单元机能开发完毕后需要往主分支上merge。
此时git merge 要用非fast模式, 这样就能 -m “新注释”,将之前的所有的commit归结为一个commit,且还有新注释。
git rebase 使用时机:
1、本地与远端同一分支提交历史不一致 log分叉问题(自己在push时,提示需要先进行pull才可push), 个人感觉此种有风险,自己未实践过,所以不建议使用。
2、不同分支之间的合并(如上自己的理解)。
rebase有冲突时:
解决冲突之后,进行git add; 之后git rebase —continue继续完成之前的rebase操作。 或者通过 git rebase —aborb 放弃rebase,恢复至之前
git rebase --skip 则会将引起冲突的commits丢弃掉(注意之前的代码会丢失);直接使用远程的
3、撤销回滚
场景一:
糟了,我刚把不想要的代码,commit到本地仓库中了,但是还没有做push操作!
情况1:
修改的文件已被git commit,但想再次修改不再产生新的Commit
# 修改最后一次提交 $ git add sample.txt $ git commit --amend -m"说明" //重置最新一次commit注释:
情况2:
已在本地进行了多次git commit操作,现在想回滚到某次的Commit
$ git reset [commit|HEAD^]
情况3:
已在本地进行了多次git commit操作,现在想撤销其中某次的Commit
revert是放弃指定提交的修改,但是会生成一次新的提交,需要填写提交注释,以前的历史记录都在;
$ git revert [commit|HEAD^]
场景二:
彻底完了,刚线上更新的代码出现问题了,需要还原提交的代码!
情况1:
注意:对远程仓库做回滚操作是有风险的,需提前做好备份和通知其他团队成员!所以考虑到这点,不能简单的处理,需要做有记录的处理。
$ git revert [commit|HEAD^]
4.tag
注意:标签总是和某个commit挂钩。如果这个commit既出现在master分支,又出现在dev分支,那么在这两个分支上都可以看到这个标签。
git tag name
打标签 默认标签是打在最新提交的commit上的
$ git tag v1.0
git tag name commit_id
有时候,如果忘了打标签,比如,现在已经是周五了,但应该在周一打的标签没有打,怎么办?
方法是找到历史提交的commit id,然后打上就可以了:
$ git tag v0.9 f52c633
$ git tag -a v0.1 -m "version 0.1 released" 1094adb
git tag -a XXX -m”XXXX”
与git tag区别
1、”git tag V1”为当前提交(commit)的附注,而不是标签的!Author和Date为当前提交的作者和日期,并非标签的。
2、git tag V2 -m"无-a有-m"
与git tag xx相比,加上-m后,标签信息多了一部分信息(Tagger和Date), 即打标签的人和日期。
3、git tag -a V3 -m"-a -m"
与git tag xx -m对比,格式是完全相同的。
总结 -a -m 格式才是正规的打标签指令
git show tagName
查看标签信息 注意: 标签不是按时间顺序列出,而是按字母排序的
用命令git show 可以看到说明文字:
$ git show v0.1
tag v0.1
Tagger: Michael Liao <askxuefeng@gmail.com>
Date: Fri May 18 22:48:43 2018 +0800
version 0.1 released
commit 1094adb7b9b3807259d8cb349e7df1d4d6477073 (tag: v0.1)
Author: Michael Liao <askxuefeng@gmail.com>
Date: Fri May 18 21:06:15 2018 +0800
append GPL diff --git a/readme.txt b/readme.txt ...
git tag
查看所有标签
git tag -d tagName
git tag -d v0.1 如果标签打错了,也可以删除,因为创建的标签都只存储在本地,不会自动推送到远程。所以,打错的标签可以在本地安全删除。
如果标签已经推送到远程,要删除远程标签就麻烦一点,先从本地删除:
git tag -d v0.9
git push origin :refs/tags/v0.9
git push origin tagName
如果要推送某个标签到远程,使用命令
$ git push origin v1.0
git push origin --tags
一次性推送全部尚未推送到远程的本地标签:
5、配置
忽略特殊文件:
.gitignore 配置文件
配置别名:
git config --global alias.st status 以后就可以用 git st 代表 git status
git config --global alias.co checkout 以后就可以用 git coi 代表 git checkout
别名配置文件:
.git/config
报错SSL certificate problem:self signed certificate in certificate chain
本地git安装完成之后,从远程git服务器上面下载代码。报错SSL certificate problem:self signed certificate in certificate chain
解决方案:打开git的控制端黑窗口,输入:
git config --global http.sslVerify false
点击Entry之后,就会去掉git的ssl验证。
然后就可以正常的下载代码。
6、创建仓库并添加代码
本地代码如何放到远程仓库上:
-
在代码跟路径上执行如下指令
git init
-
在github上创建仓库,复制仓库链接
-
执行命令,将代码push到远程仓库; git remote add origin 链接
git remote add origin https://github.com/tugenhua0707/testgit.git
-
git push -u origin master