Git使用
一、本文简介
Git:分布式代码管理工具。本文仅对GitBash的命令使用做介绍。面向有一定Git基础的读者。
git工作流程
Remote:远程仓库
Repository:本地仓库
Index:暂存区(也叫stage)
workspace:git checkout -b 到的新分支
index ——> workspace:git checkout file 用暂存区的文件覆盖工作区中的文件 (上面少画一条线)
下载和提交
$ git init 文件夹名:这个文件夹下就有.git,这个文件夹就作为一个仓库。
工作区:简单理解就是需要进行版本的某个文件夹,这个文件夹有一些特殊之处——多了.git这个隐藏的文件夹,就是本地下载有代码的文件夹。
暂存区:可以理解为一个虚拟工作区,这个虚拟工作区会跟踪工作区的文件变化(增删改等操作)。这个工作区的位于.git文件夹下的index目录下。
二、操作命令简介
2.1、远程仓库相关命令
检出仓库:$ git clone git库
查看远程仓库:$ git remote -v
添加远程仓库:$ git remote add [name] [url]
删除远程仓库:$ git remote rm [name]
修改远程仓库:$ git remote set-url –push [name] [newUrl]
拉取远程仓库:$ git pull [remoteName] [localBranchName]
推送远程仓库:$ git push [remoteName] [localBranchName]
如果想把本地的某个分支例如test提交到远程仓库:
1 | git push // 默认只推送当前分支 |
2.2、分支相关命令
查看本地分支:$ git branch (所有本地分支将罗列出来,本地当前分支前会加一个*,以示区分)
查看远程分支:$ git branch -r
查看本地分支和远程分支:$ git branch -a (此时远程分支以remote开头))
创建本地分支:$ git branch [branch name] (注意新分支创建后不会自动切换为当前分支)
切换分支:$ git checkout [branch name]
创建新分支,并立即切换到新分支:$ git checkout -b [name]
创建新分支,并立即切换到新分支,并关联远程分支:
1 | //第一种 |
删除分支:$ git branch -d [name] —- -d选项只能删除已经参与了合并的分支,对于未有合并的分支是无法删除的。如果想强制删除一个分支,可以使用-D选项
合并分支:$ git merge [name] —-将名称为[name]的分支与当前分支合并
创建远程分支(本地分支push到远程):$ git push origin [name] [romte name]
删除远程分支:$ git push origin :heads/[name] 或 $ git push origin :[name]
- 基于本地某分支代码push出一个新分支到服务器
在某分支下去切换的新分支,新分支就含有该分支的代码1
2
3
4
5
6
7//第一种操作方法:
git checkout -b 新分支名 //新建并切换到一个新本地分支
git push origin 新分支名 //push新分支到服务器
git branch –set-upstream-to=remotes/origin/远程新分支名 //关联远程分支
//第二种操作方法:
git checkout -b 新分支名 //新建并切换到一个新本地分支
git push -u origin 新远程分支名 //push新分支到服务器,并远程分支 - 更新本地存储的origin远程上的分支列表
1
git remote update origin --prune
- 创建一个新的空白的分支出来
1
2
3git checkout -b 新分支名
git rm -rf .
//(执行命令之前记得先提交你当前分支的修改,否则会被强制删干净没得后悔)2.3、版本(tag)相关命令
查看版本:$ git tag
创建版本:$ git tag [name]
删除版本:$ git tag -d [name]
查看远程版本:$ git tag -r
创建远程版本(本地版本push到远程):$ git push origin [name]
删除远程版本:$ git push origin :refs/tags/[name]
合并远程仓库的tag到本地:$ git pull origin –tags
上传本地tag到远程仓库:$ git push origin –tags
创建带注释的tag:$ git tag -a [name] -m ‘yourMessage’
三、常用操作
git pull :从服务器仓库中获取代码后,与本地合并(相当于Git fetch + Git merge)
(git pull指令一定当前仓库下要有对应的branch,否则拉不下来。)
git push :把一个仓库的主分支上的内容推送到另一个仓库或服务器仓库
(只把处在commit状态的文件push上去)
git fetch :获取服务器上的更新,但不会自动合并,比pull更安全。
git status :查看当前状态。介绍如下:
- 仓库内新建的文件:处于Untracked files (新建状态/不在git库中)
- 仓库内已有并修改的文件:处于Changes not staged for commit (修改状态/工作区)
- 仓库内add后的文件:处于Changes to be committed (add状态/暂存区)
- 仓库内commit的文件:提示nothing to commit
- 仓库内merge失败的文件:处于Unmerge paths
git diff :比较当前目录和仓库中数据的差异。
最后会出现(END),如何退出,按Q键返回。
gitk:可以查看每一笔的提交记录。
git log:也可以查看提交记录和commit的SHA1值(ID)。
git cherry-pick:在A分支上的提交,提交到B分支上。如下: git rm 文件名 : 还可以去删除版本库里的文件1
2
3
4//切换到B分支下:
$ git cherry-pick A分支的某commitid
$ git push
(使用后,如果没有冲突就处于commit状态;git cherry-pick -n,加个-n参数,不会处于commit状态,处于已add状态。)
git clean :命令用来从你的工作目录中删除所有Untracked files区的文件。
就是删除一些没有git add过的文件。 - git clean -n 显示 将要删除的Untracked files区的文件 和 目录
- git clean -f 文件名: 删除 文件
- git clean -df 文件名/目录: 删除 文件 和 目录
- git clean -fdx : 强制删除Untracked files区的 文件 和 目录
执行清理工作,避免前一次编译的遗留文件对编译造成影响。注意,下面的操作将丢弃本地对Git代码的改动。
git rm 从暂存区里面删除内容
git mv 工作区内重命名文件或者移动文件,然后再把他们添加到暂存区
四、git reset 和 git revert
4.1、git reset命令
过程:直接删除指定的commit (分三种状态回退)。
理解:回退到指定的提交 —指定的提交及之前的commit和history都会保留,之后的记录都被删除。
git reset [-q] [commit] [–]
git reset [–soft | –mixed | –hard | –merge | –keep] [-q] [
(不覆盖:就是仍保留;覆盖:就是status往前推。)
HEAD就是当前节点,HEAD^就是上一节点,也可以用commitID指定哪个节点
- 回退到最近提交,不覆盖最近的暂存区和工作区
git reset –soft HEAD
理解:1/节点不往前推,仓库代码仍是最近commit状态,2/因本来就是最近状态,相当于不起作用 - 回退到最近提交,覆盖最近暂存区,不覆盖工作区
git reset –mixed HEAD
理解:1/节点不往前推,仓库代码仍是最近commit状态,2/最近操作add暂存区的文件回到工作区 修改状态 - 回退到最近提交,覆盖最近暂存区和工作区
git reset –hard HEAD
理解:1/节点不往前推,仓库代码仍是最近commit状态,2/最近暂存区和工作区的文件被撤回 - 回退到上次提交,不覆盖上次和本次操作的暂存区和工作区
git reset –soft HEAD^
理解:1/节点往前推一次,仓库代码回到上次commit状态,删除最近commit的代码和记录。
2/git status查看到上次操作的add后状态;
git status查看到本次add状态和修改状态。 - 回退到上次提交,覆盖暂存区和工作区
git reset –hard HEAD^
理解:1/节点往前推一次,仓库代码回到上次commit状态,删除最近commit的代码和记录。 - 仓库代码回退到这个ID对应的提交状态
git reset –hard commitId
先通过git reflog/log找到上一次的历史提交记录id,id会保存记录一段时间的。
上一次 HEAD | HEAD~0
上两次 HEAD^ | HEAD~1
上三次 HEAD^^ | HEAD~2
commitId 指定回退某提交4.2、git revert命令
过程:逆向操作+重新提交,并是一个最新的提交,有提交记录。
理解:撤销指定的提交 —指定的提交,之前及之后的commit和history都会保留,并把这次撤销提交作为一次最新的提交。
(如果要撤销的提交已push到服务器,则git revert后要push一下。)
git revert和SVN的逆向merge几乎如出一辙,就是将你需要回滚的那次commit所做的所有操作,反向操作一次,然后重新做一一个单独的commit对象进行提交。 - 撤销最近一次 commit ,撤销也会作为一次提交进行保存
git revert HEAD - 撤销上一次 commit ,撤销也会作为一次提交进行保存
git revert HEAD^ - 撤销指定ID的版本,撤销也会作为一次提交进行保存
git revert commitID
所以,可用git reset –hard对git revert的操作进行回退。
4.3、git revert 和 git reset的区别:
1、git revert是用一次新的commit来回滚之前的commit,git reset是直接删除指定的commit。
2、在回滚这一操作上看,效果差不多。但是在日后继续merge以前的老版本时有区别。因为git revert是用一次逆向的commit“中和”之前的提交,因此日后合并老的branch时,导致这部分改变不会再次出现,但是git reset是之间把某些commit在某个branch上删除,因而和老的branch再次merge时,这些被回滚的commit应该还会被引入。
3、git reset 是把HEAD向后移动了一下,而git revert是HEAD继续前进,只是新的commit的内容和要revert的内容正好相反,能够抵消要被revert的内容。
五、回退操作
一般,我们的回退都是当前操作下的回退,并想保留工作区或暂存区的文件,下面以最近一次回退为例介绍。
主要是采用上述四介绍的命令。
5.1、工作区的回退
就是在工作区内修改文件后,未add到暂存区,想恢复原来的修改:使用 git checkout。
1 | git checkout file名 //修改文件后(其他什么也没继续做),其实是用最新暂存区的文件覆盖了修改文件 |
5.2、暂存区的回退
就是文件已经add到暂存区,或误添加,想把add状态的文件回退到工作区:使用 git reset –mixed HEAD。
1 | git reset HEAD file名 //只把<file>文件回退到add状态之前 |
5.3、提交后的回退
就是文件已经commit到仓库,想把提交的文件回退回来:使用 git reset。
1 | git reset --hard HEAD //提交的文件全部回退到本次操作修改前(被撤回) ---慎用 |
5.4、不管什么状态都能用,但是要知道使用的后果
1 | git reset –hard //慎用 |
六、git checkout 和 git cherry-pick
单独对git checkout 和 git cherry-pick 作详细介绍。
6.1、git checkout
- git checkout file名 :修改文件后(其他什么也没继续做),其实是用最新暂存区的文件覆盖了修改文件
- git checkout [-q] [commitID] [–] paths …
既可以是某一个具体的commit hash值,也可以是某个分支名称,tag名称。不论分支也好,tag也好,它们本质上对应的都是一个commit hash值。
该用法(包含的用法),不会改变HEAD头指针,主要使用于指定版本的文件覆盖工作区中对应的文件。
如果省略,则会用暂存区的文件覆盖工作区中的文件,否则用指定提交中的文件覆盖暂存区和工作区中的对应文件。 - git checkout [branch]
该用法,单纯的检出某个commit或分支,是会改变HEAD头指针的。而且只有当HEAD切换到某个分支的时候才可以对提交进行跟踪,否则就会进入“分离头指针”的状态。如果省略用法后面的,则默认对工作区进行状态检查。 6.2、git cherry-pick问题
git cherry-pick xxx
fatal: bad object xxx
原因:一个git有多个分支,来回切换分支麻烦,就在本地创建多个文件夹切换每个分支下的代码。在这个文件夹下的分支下,提交代码后,再想cherry-pick另一个文件夹下的另一个分支就会报这样的错误。
解决:git cherry-pick是本地特性,本地要有这个commit才可以被git cherry-pick。
这个文件夹下没有另一个文件夹下的commit,所以cherry-pick使用的前提是在同一路径下的不同分支下使用。
注意点:
如果git cherry-pick comintID的时候,出现不能节点时的merge branch的情况时,不能用merge的comintID(cherry-pick会失败),要使用原本提交的comintID。
本文引用文章链接如下:
http://blog.sina.com.cn/s/blog_4f3b79d0010166ab.html
http://www.cnblogs.com/ShaYeBlog/p/5575852.html
http://www.cnblogs.com/ppforever/p/4914876.html
https://www.zhihu.com/question/21995370
http://blog.csdn.net/wh_19910525/article/details/7554430
http://blog.jobbole.com/78960/
本文链接: https://www.yinhanlei.com/2019/11/26/devel_git/
版权声明:本作品采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可。若转载、摘录本博客内的作品,请注明出处!
侵权告知:如果本博客内涉及到任何侵权内容,请通过邮件[email protected]告知侵权内容。 本人看到邮件后将立即标注原文出处或删除侵权内容。