本文共 15222 字,大约阅读时间需要 50 分钟。
软件的开发过程中:
开发完成一个版本1后,打包,部署。 然后继续开发,定制新功能,增加新代码… 某一天,需要再打包一个 版本1.此时项目中已经新增了很多代码,甚至而且还有好多新代码尚在开发测试中…
开发过程中,完成了一个功能A。
继续写其他功能,增加新代码… 某一天,突然发现新功能的实现,就是一堆垃圾,完全不能使用,项目代码需要恢复到 刚写完功能A的状态… 某一天,突然发现新功能被砍啦,项目代码需要恢复到 刚写完功能A的状态… 某一天,突然发现接到新任务,需要对功能A进行改进,然后打包,部署,而此时项目中功能B的代码已然很多,且功能B尚未完成…
Git是一个开源的分布式版本控制系统,用于敏捷高效地处理任何或小或大的项目。
Git 是 Linus Torvalds 为了帮助管理 Linux 内核开发而开发的一个开放源码的版本控制软件。 Git 与常用的版本控制工具 CVS, Subversion 等不同,它采用了分布式版本库的方式,不必服务器端软件支持。Git是目前世界上最先进的分布式版本控制系统(没有之一)
官网:
文档:
版本控制发展:
原始的版本控制:项目写完一个功能,就复制一个项目副本。进而有多个项目的版本,可以通过不同的文件夹切换不同版本。此种方案会有大量的文件出现,且不适合长线作业,终会陷入管理混乱
本地化的版本控制:引入一些管理软件,帮助管理本地的多个版本。此种方案不能共享他人,不能多人协同开发
集中化的版本管理:一个版本服务器,多个贡献者,贡献者将代码提交到服务器,并从服务器下载他人的代码。 此种版本可以协同开发。典型工具如
Subversion,CVS
。但由于版本控制集中在服务器中所以存 在单点故障问题。分布式版本管理:多个贡献者本地都有完整的控制版本功能,可进行版本管理。且通过一个版本服务器共享彼此的代码。 是本地化和集中化的汇总。好处:没有单点问题,不强制依赖服务器,不强制依赖网络环境。典型工具 如
Git
下载git | 下载TortoiseGit |
---|---|
Git安装除了安装位置外,其他一直下一步即可。
# 安装后,打开cmd ,自报家门# 如下信息会在提交代码时要使用,记录在你的每次提交中。以后才知道哪次提交是谁做的,"git log"可以查看# 执行:git config --global user.name "Your Name" #用户名git config --global user.email "email@example.com" #邮箱# 查看信息git config -l测试:cmd中执行
git version
查看git版本
对应的就是一个
目录
,这个目录中的所有文件被git管理起来。以后会将一个
项目的根目录
,作为仓库。仓库中的每个文件的修改、删除 git都能跟踪。
**创建版本仓库:**创建一个文件夹,cmd指向该文件夹,然后执行
git init
即可
.git目录
保存仓库的所有内容**新增文件:**在文件夹中创建一个文件: xx.txt ,然后cmd执行该文件夹,
执行
git add xx.txt
增加一个文件,如果出现转移字符问题,可以采用git config --global core.autocrlf false
git add xx.txt xx2.txt
增加多个文件
git add abc
增加当库目录下的abc目录中的所有文件
git add .
增加库目录中所有文件提交文件:
git commit -m "this is a test file"
【-m 后是对本次提交的描述】【提交添加的所有文件】
git commit hello.txt hello2.txt -m "this is a test file"
提交某些文件
git commit -a -m "this is a test file"
自动add并commit所有已跟踪并修改或删除的文件文件状态:
git status
在提交后,如果文件有改动,可以看到文件改动:
git diff hello.txt
查看该文件的改动情况注意:每次对库中内容改动后,都需要 add 和 commit操作,同步git,git中会记录当前仓库的快照(版本)。
删除文件:
git rm hello.txt
并git commit hello.txt -m "xxx"
即可
帮助:
git help commit
或git commit --help
每次 commit,随着版本的记录,也会留下日志。
执行:
git log
# 显示从最早的提交点 到 当前提交点的 日志
git log --oneline
#简洁日志显示git log --oneline -2
#简洁日志显示,最近2次提交日志 git log --oneline --graph
#图形化显示分支走向
# commitID 描述1094adb7b9b3807259d8cb349e7df1d4d6477073 (HEAD -> master) append xxxe475afc93c209a690c39c13a46716e8fa000c366 add wordseaadf4e385e865d25c48e7ca9c8395c3f7dfaef0 add one line
注意git的
commitID
是通过SHA1计算出来的一个非常大的数字,用十六进制表示,在分布式中保证唯一。
每次的修改文件并add、commit 。git中也会记录一个版本。如果有需要可以回退到之前的一个数据版本状态。
执行:
git reset --hard HEAD~
# 回退到上一个版本
git reset --hard HEAD~~
# 回退到上上一个版本
git reset --hard HEAD~5
# 回退到上5个版本
执行:
git rest --hard e475a
#回退到commitID 为 "e475a…"的版本, commitID可以只写前几位,唯一即可。e475afc93c209a690c39c13a46716e8fa000c366=commitID, e475a是commitID的前几位
总结:1> 每次commit,git都会保留一个版本,每个版本都有一个全局唯一的commitID
2> git有个游标:HEAD
,指向当前的版本,所以可以移动游标来回退版本
3> 也可以通过 commitID 回退到某个版本
4> 回退并不会删除任何版本,所以版本间可以来回切换
细节:发生版本回退后,通过
git log
只能看到最原始提交点 至 当前提交点的 日志。git reflog
可以看全部日志
ALT+9 表示调取【Version Control】在idea中可以进行版本回退操作
仓库:就是第二章中,执行了
git init
的目录
版本库:工作区中有一个隐藏目录
.git
,这个目录不属于工作区,而是git的版本库
,是git管理的所有内容暂存区:版本库中包含一个临时区域,保存下一步要提交的文件。
分支:版本库中包含若干分支,提交的文件存储在分支中
工作区-版本库-暂存区 |
---|
1. 文件首先出现在工作区,如果需要有git管理,则通过 git add xx 将文件添加到暂存区 通过 git commit ... 将暂存区的文件y一次性提交到分支 中 同时提交行为将触发git的一次commit日志记录。 2.关于分支 是git的一个重要概念,后续讲解,master分支是安装git时默认创建的 |
切换到某分支,在工作区操作其文件,文件的状态会有如下可能:
- 未跟踪
- 工作区中新创建的文件,git中并未保存它的任何记录
- git add 增加到暂存时,即可建立跟踪
- 修改
- 已跟踪的文件,在工作区被修改了。
- 暂存
- git add 的文件,处于暂存状态。
- 每次暂存的是文件的当时状态,如果暂存后又做了修改,需要再次 git add文件。
- 每次提交时,是将所有暂存的文件提交。
- 提交
- git commit 的文件,处于提交状态。
- 每次提交,增加一个快照版本,分支指针后移,指向最新版本。
在工作区中一系列操作后,要查看文件状态:
执行:
git status
可以看到文件状态:On branch master #分支 master
Changes to be committed:#说明有内容在暂存区可以提交
(use “git reset HEAD …” to unstage)modified: hello.txt
On branch master #分支 master
Changes to be committed:#说明有内容在暂存区可以提交
(use “git reset HEAD …” to unstage)modified: hello.txt
Changes not staged for commit:
(use “git add …” to update what will be committed) (use “git checkout – …” to discard changes in working directory)#说明有内容没有增加到暂存区
modified: hello.txt
细节:通过
git diff
比对变动情况:
git diff hello10.txt
比对工作区和暂存区(若暂存区没有,比分支)
git diff HEAD -- hello10.txt
比对工作区和分支中的最新结果 ( 了解或忽略此点 )
git diff --staged hello10.txt
对比暂存和分支中的最新结果 ( 了解或忽略此点 ) 坑:
-- hello10.txt
之间需要分隔,不能写成--hello10.txt
如果在工作区文件中添加了如下一行,你突然意识到饭碗可能不保,所以需要撤销修改
...My stupid boss still prefers SVN.
执行:
git checkout -- hello9.txt
可以撤销到最近一次git add 或 git commit
的状态即:如果 暂存区有此文件,则将暂存区中的文件内容恢复到工作区。 如果 暂存区没有此文件,则将分支中的文件内容恢复到工作区。
注意:
-- hello9.txt
一定不能少写--
,否则就是其他语意啦。
如果在工作区中修改了文件并发送到暂存区中,但文件中有需要撤销的内容
则可以执行:
git reset HEAD hello9.txt
将hello.txt在暂存区的内容清除。然后可执行:
git checkout -- hello9.txt
回退到上一个版本
就是一条时间线,线上每个点都是一次提交,都记录了当时的文件快照。
1> 默认有一个分支,master。
2> 分支中接收 git commit 提交的内容,为一个一个不断向前发展的提交点。每个提交点都保存一个代码版本。
3> 每个分支,都有一个指针,指针默认指向最近一次提交的版本。
4> 工作区中的内容,初始状态,就是指针所指向的版本状态。
5> 基于指针指向的版本代码,在工作区中做进一步的编码,功能完成后,即可 git commit,在分支中形成新的提交点,指针也后移一步。
6> 然后再在工作区中,添加新代码,功能完成,再 git commit,又形成新的提交点,指针再次后移。
如此反复,不断开发,不断记录版本。
7> 当有需要时,可以回退指针到某个提交点,在工作区中即可得到之前的某个版本的代码。
如下是分支效果图: |
---|
情景1:在编写一个功能时,需要一周的时间,在一周之间可能会有多次提交,但最后却发现有问题,那这些有问题的提交点就掺杂在master分支中。使master分支很混乱;
情景2:在编译一个功能时,有一个临时的思路,但不确定能否最终实现预期功能,只能试着编写,最后发现不成立,则提交过的所有提交点都无效,也会掺杂在master分支中。
而且如果是多人协同开发,有可能影响到其他人的开发进度。
实际开发中master分支我们只愿意存放稳定的代码提交,保证master分支稳定,有效。
方案1:一直不提交,等所有都写完后,提交一次。虽然可以保护master分支,但开发过程中缺乏版本控制点,易丢失工作。
方案2:在需要编写新功能时,新建一个开发用的分支,所有改动都在该分支上提交,在功能完整实现后,将该分支的最终内容合并到master分支,这样,既保证开发中有多个版本可以控制,又保证master分支是稳定,有效的
方案2,实施过程: |
---|
在某个库目录中,执行:
`执行`:git branch new_branch #创建分支,会和当前分支保持同样的数据状态,即新分支和当前分支指向同一个提交点`执行`:git checkout new_branch #切换分支,工作区中显示当前分支的内容。( 切换分支,实际只是在切换指针 )`执行`:git branch #查看当前分支 git brach -vv #查看分支详细信息( 分支信息,所跟踪的远程分支信息,是否领先远程分支等 )
新分支改动完成后,切换到master分支:
`执行:git branch master #切换到master分支`执行:git merge newBr #合并newBr分支
如上就进行了合并,此次合并就是将master的指针移到了newBr的位置 == 快速合并。
合并后,新分支如果不再使用,可以删除 (了解):
`执行:git branch --merged #查看被当前分支合并了的 分支( ops:删除分支前,先确认其已被合并,保证工作不丢失 ) `执行:git branch -d newBr #删除newBr分支
人生处处有惊喜,分支开发怎么可能一直这么顺利,在合并过程中分支间会有不和谐出现。
场景如下 |
---|
1> 创建新分支。分支图1 |
2> 切换到新分支,并在文件最后添加 “ hello CHINA” ,然后提交。分支图2 |
3> 切换回master分支,并在文件最后添加 “hello china” 后提交。分支图3 |
4> 在master分支中合并newBr分支。合并中出现冲突。分支图4 |
冲突点:两个分支对同一个文件都做了改动,所以在合并时git会无法确定保留哪个分支的改动。 |
执行:
git merge newBr
时,提示:
Auto-merging hello.txt
CONFLICT (content): Merge conflict in hello.txt
Automatic merge failed; fix conflicts and then commit the result.
#合并出现冲突后,git将双方的修改都保留了,并且用 <<<< ====== >>>>> 做了分隔hello world<<<<<<< HEADhello china=======hello CHINA>>>>>>> newBr
此时需要人为手工修改,比如我们最终改为
hello China
#手动改为如下:hello worldhello China
执行:
git add hello.txt
git commit hello.txt -m "conflict handle"
# 重新提交执行:
git branch -d newBr
# 如果分支不再使用,删除新分支即可
执行:
git merge --abort
#中止合并,发生冲突时可以选择撤销本次合并执行:
git merge dev2 -Xignore-all-space
#避免因为空白导致冲突( 了解 )
git在保存每个版本时( 对应提交点 ),并不是复制所有文件,没有改动的文件只是记录一个链接
快速合并 |
---|
三方合并 |
Git是分布式版本控制系统,同一个Git仓库,可以分布到不同的机器上。怎么分布呢?最早,肯定只有一台机器有一个原始版本库,此后,别的机器可以“克隆”这个原始版本库,而且每台机器的版本库其实都是一样的,并没有主次之分。
实际情况往往是这样,找一台电脑充当服务器的角色,每天24小时开机,其他每个人都从这个“服务器仓库“克隆一份到自己的电脑上,并且各自把各自的提交推送到服务器仓库里,也从服务器仓库中拉取别人的提交。
完全可以自己搭建一台运行Git的服务器,不过现阶段,为了学Git先搭个服务器绝对是小题大作。好在这个世界上有个叫GitHub的神奇的网站,从名字就可以看出,这个网站就是提供Git仓库托管服务的,所以,只要注册一个GitHub账号,就可以免费获得Git远程仓库。
当然国内也有git服务器:码云 公司内部往往会搭建自己的git服务器,可能选型为: gitlabgit本地库和 github 或 码云 之间传输,建议设置SSH key,避免在传输中反复输入密码
执行:
ssh-keygen -t rsa -C "zanghongjiu@sina.com"
然后一直回车即可 -C后"可以随意写一个,作为key的title而 已,无关紧要"最后:在
C:\Users\主机名\.ssh
目录下生产秘钥文件,
id_rsa
是私钥,不能泄露出去,id_rsa.pub
是公钥,可以放心地告诉任何人。登录GitHub,在账户设置中,选择 “SSH Keys” ,在Title中随便填写一个,在Key中填写
id_rsa.pub
文件中的所有内容即可。
这样和Git服务器通信时(clone,push,pull) git服务器就可以识别出你的身份。
识别出你是谁;你是否有权限访问某个远程库;你是否可以上传你的代码。
将本地git库 和 远程github库建立关联。可以方便本地库和远程库的
push和pull
# 添加远程库 远程库别名 库地址git remote add origin git@github.com:zanghongjiu99/repo.git # 注意:origin是默认会有的别名git remote add test git@github.com:zanghongjiu99/repo2.git # 还可以设置自己的别名git remote -v # 查看关联的所有远程库git remote rm origin # 删除origin重新定义git remote show origin # 关联远程库后,本地分支和远程分支的对应关系git remote remove origin # 删除关联git remote rename origin origin2 # 重命名
将本地master分支的内容上传到 关联的远程库中,push结束后在github中可见
# 本地的master分支上传到与之有跟踪关系的远程分支中,(克隆时就会建立跟踪关系),如果远程分支不存在,则会建立远程分支git push origin master# 本地存在分支dev,上传到远程库origin的分支dev,如果没有dev,将建立远程分支devgit push origin dev:dev# 本地库dev:远程库dev 本地库dev2:远程库dev2git push origin dev:dev dev2:dev2# push动作,其一需要你有权限push,其二需要在你pull之后没人push过。(乐观锁机制)
拉取远程的新内容,存于本地版本库。
注意:并没有合并到本地库的分支中,需要通过 merge 手动合并
# 拉取远程 master分支中本地没有的内容(即其他开发者push的内容),git fetch origin master # 拉取的分支名为 ”origin/原始分支名“存储位置:【.git\refs\remotes\origin】git merge origin/master #把拉取下来的master分支的内容 合并到本地库中的分支上# 如上两个指令可以将git服务器上的最新版本状态同步到本地库中# 拉取所有分支的的内容(本地没有的,其他开发者push的内容)(假定有分支:dev2,dev3) (先忽略,如果你已经掌握了第五章可以回头来看)git fetch origingit checkout dev2 并 git merge origin/dev2 #切换到dev2分支,并合并拉取下来的内容git checkout dev3 并 git merge origin/dev3git checkout dev2 并 git diff origin/dev2 #切换到dev2分支,比较拉取的内容中的dev2分支 和 本地dev2分支的不同
等价于
git fetch + git merge
拉取远程的新内容,并合并到当前分支
# 语法格式:git pull <远程主机名> <远程分支名> : <本地分支名> # 完整写法git pull origin master:master# 省略本地分支名 = master:当前分支(缺省)git pull origin master# 省略本地分支名 = dev:当前分支git pull origin dev# 拉取远端origin的所有分支中的改变,并将属于当前分支的改变自动mergegit pull origin# 更新远程分支git pull 本地分支名> 远程分支名> 远程主机名>
下载远程库中的内容,注意clone操作会自动搭建关联,即
5.3
中所描述的。
# 任意新建一个目录,并执行:git clone git@github.com:zanghongjiu99/repo.git #ssh 地址,将远程库clone到本地,已设置key,不用口令git clone https://github.com/zanghongjiu99/zhj_repo.git #https地址,需要输入github口令
细节:clone 只在初次从git服务器下载项目时执行一次,后续在需要同步应该执行
pull 或 fetch
当你执行
git clone
命令的时候,默认配置下远程 Git 仓库中的每一个文件的每一个版本都将被拉取下来。
项目管理员( 项目经理 )
1> 由管理员负责创建一个远程库,初始的库中什么也没有,成为裸库,如5.2中所述。库的名称建议和项目同名
2> 管理员会在idea中创建一个空项目,其中包含
.gitignore文件
。 并在项目根目录下git init
. 建立本地库。并建立dev分支
。3> 管理员将本地库同步到远程库:
git push 远程库地址 master:master dev:dev
4> 将其他开发人员拉入远程库的
开发成员列表中
,是的其他开发人员可以访问该远程库。5> master分支设置为
protected分支
,只有管理员有权限将代码合并到其中。dev分支设置为常规分支
所有开发人员 都可以其中合并代码
开发人员
1> 初始化:在cmd或idea中
clone
远程库,获得项目。执行git clone 远程库地址
即可。会建立本地库2> 获得项目时,本地库中只显示master分支,需要执行:
git checkout dev
即可获得dev分支。3> 后续的开发中,都要在dev分支上进行。开发完一个功能并测试通过后就可以
git add ..
并git commit ..
提交到本地的dev分支中,然后git push 远程库地址 dev
同步到远程dev分支中。 是否需要在本地master中合并下?4> 注意如果在
git push
远程库时,有人比你早一步git push
,git服务器将拒绝你的git push
.(乐观锁原理) 不过很简单,你需要git pull 远程库 dev
并git merge origin/dev
,然后再git push
即可。 理想状态:远程有的代码,本地都有,远程没有的代码,本地也有,这样push是最好的。所以需要pull一次,进行一次合并,然后再push
后续的开发,会接到一个个的功能任务,往复操作 3> 和 4> 而已。
效果
在实际开发中,我们应该按照几个基本原则进行分支管理:
首先,
master
分支应该是非常稳定的, 也就是仅用来发布新版本,平时不能在上面干活;那在哪干活呢?干活都在
dev
分支上,也就是说,dev
分支是不稳定的,到某个时候,比如1.0版本发布时,再有管理员把dev
分支合并到master
上,在master
分支发布1.0版本;你和你的小伙伴们每个人都在
dev
分支上干活,每个人都有自己的分支,时不时地往dev
分支上合并就可以了。所以,团队合作的分支看起来就像这样:
ops:如上4个分支,由上而下分别是【远程master,远程dev,micheal的本地dev,bob的本地dev】
在众多的提交中,总有些提交是尤为重要的,比如重大bug的解决,比如一个新版本的发布等。这些提交身处分支的众多提交点中,可以为他们
打标签
,让他们更显眼
,可以更快速的找到他们。
# 创建轻量标签git tag v1.1.0# 创建附注标签 ( 就是带说明的轻量标签 )git tag -a v1.1.1 -m "说明文字"#注意,创建的标签会自动 打在最近的提交点上#如果要给过往的提交点 追打标签,需要 git log 去查看提交点的 “commitID”git tag [-a] v1.1.1 "commitID"
#查看所有分支上的所有标签 ( 查看标签并不区分分支 )git tag#查找标签名以 “v1.1”开头的标签git tag -l "v1.1*" #显示标签 及其对应的提交点信息git show v1.1.0
标签不会随提交点一起 提交到远程服务器,需要单独push。
pull时,标签会一同被下载到本地
# 同步一个标签 “v1.1.1” 到git服务器git push origin v1.1.1# 同步所有标签 到git服务器git push origin --tags
标签删除需要在本地和远程分别删除。
# 在本地删除标签git tag -d v1.1.1# 删除远程库中的标签git push origin :refs/tags/v1.1.1
标签主要用于发布版本。
假定已经为各个发布版本打了标签:
v1.0 v1.1 v2.0 ....
现在需要
1.0版本
# 分离一个指针到 v1.0提交点位置git checkout v1.0 #( 分离头指针,是一个临时指针,不归属任何分支 )git checkout commitId #( 分离头指针,是一个临时指针,不归属任何分支,不如标签方便 )# 然后将工作区的代码打包(jar或war)即可。mvn package# 最后随意切一个分支,分离头指针消失。什么也没发生过。git checkout ”任意分支“
一些指令比较麻烦,可以定义别名,简化书写。
git config --global alias.ck checkout # git ck等价git checkoutgit config --global alias.commit "commit -m" # git commitm 等价 git commit -mgit config --global alias.br branch # git brgit config --global --unset alias.commitm # 删除alias.commitm
可以在idea中双击shift 搜索【versionControl】然后在窗口中点击【log】可以查看提交分支图
操作过程见下图 |
---|
注意在idea做开发时,一定要先切到
dev分支
,在dev分支上编码。完成一个阶段编码后,可以提交代码
1. 可以通过指令: |
---|
2. 可以通过idea图形界面: |
---|
当然可以在idea的 “Terminal”面板执行:
git push origin dev
.如下演示idea的图形界面操作
本地分支同步到远程分支:push |
---|
push结束后,可以到 “Version Controll” 面板 查看 “Console” ,获知push结果。 |
1. 和如上一样,在idea的
“VCS” ==> "Git"==> "Fetch"
抓取远程库中的新内容2. 准备合并远程库上的内容:
“VCS” ==> "Git"==> "Merge Changes..."
3. 最后如下图:.
在idea开发时,会有很多和项目本身无关的文件
还有一些是不能共享的项目文件,比如包含自己数据库信息的 db.properties
还有java的字节码文件
idea产生的文件 | 项目中的不能共享的配置文件 |
---|---|
此类文件,不必出现在版本控制中,可以在项目根目录下创建忽略文件:
.gitignore
,文件中定义:
# 所有class后缀的文件*.class# 所有jar后缀的文件*.jar*.iml*.war# .idea 文件夹.idea# 所有.txt 文件*.txt# 数据库连接参数 文件db.properties# abc.txt除外,不忽略!abc.txt*.class*.jar*.war*.nar*.ear*.zip*.tar.gz*.rardb.properties*.class*.iml.idea*.txt
关于忽略文件,在github上,码云上都有模板,针对各种语言都有
码云:
github:
可以下载使用,并添加自己的文件或目录
功能还没写完,还不适合提交,但此时需要去解决另一个bug,需要切换分支,则当前功能工作区中的改动会被新分支的内容覆盖,所以此时可以先储存下当前功能的内容,然后就可以放心的切换到其他分支先干别的事,过后再回来。
git stash
:储存当前修改( 未提交的内容 ,包括未暂存和已暂存的)# 分支 文件Saved working directory and index state WIP on dev: a795274 dev commit Test.java
git stash list
:查看存储列表# 标识 分支 储存文件stash@{0}: WIP on dev: a795274 dev commit Test.java
git checkout 其他分支
:可以放心的切到其他分支,完成其他工作
git checkout dev
:切回dev分支,并:git stash apply
:恢复储存的工作,继续编码注意:没用的存储建议删除:
git stash drop stash@{0}
:删除某一个储存点
git stash clear
:清空所有储存点
三种回退模式:mixed、hard、soft,默认mixed。
回退是指:提交点回退。就是在某个分支上指针后移。回到之前的某个版本。
# 基本使用: 当前分支 指针回退两步,就是回退到上上一个提交点。(无论是 mixed,soft,hard)git reset HEAD~~git reset HEAD~2# 基本使用: 当前分支 指针指向到对应commitID的的提交点git reset commitID
会退时,除了指针必然移动,还有些细节:
##################### Soft ########################### 指针后退一步,但暂存区内容不变,工作区内容不变git reset --soft HEAD~加入有3个提交点,依次为 A --> B --> CA中:添加一个文件abc.txtB中:修改abc.txt,及其他一些修改C中:添加一个文件def.txt 并提交。C中:继续修改,并最终完成功能,做最终提交。可以还有一种选择:【先从C回退到A,然后再提交,提交点就变为:A --> D.提交后内容总量不变,但起到提交点被压缩】
##################### Mixed ########################### 指针后退一步,但暂存被清空:即版本库回到了上次提交的状态。 但工作区不变。git reset --mixed HEAD~# 然后执行:git checkout -- abc.txt #从版本库中拉取abc.txt文件,可以将工作区的某个文件回退到上个版本############################################### 或者执行,达到将暂存内容清空git reset --mixed HEAD #指向当前提交点,其实没回退指针,但会清空暂存。# 然后执行:git checkout --abc.txt ##从版本库中拉取abc.txt文件,恢复当当前版本的原始状态 ( 撤销了所有修改 )
###################### Hard ############################指针后退一步,暂存清空,且将工作区也同步到指针所指的状态git reset --hard HEAD~ # 用于拉取某个特定提交点的文件
提交后发现有问题,比如有些注释忘记修改,比如提交描述不够详细等等。
当然可以修改后,在提交一次,但是还有更好的办法:
git commit --amend -m"xxxxx"
:会再次提交并替换上次提交
千峰gitlab
.txt 并提交。
C中:继续修改,并最终完成功能,做最终提交。可以还有一种选择: 【先从C回退到A,然后再提交,提交点就变为:A --> D.提交后内容总量不变,但起到提交点被压缩】```sh##################### Mixed ########################### 指针后退一步,但暂存被清空:即版本库回到了上次提交的状态。 但工作区不变。git reset --mixed HEAD~# 然后执行:git checkout -- abc.txt #从版本库中拉取abc.txt文件,可以将工作区的某个文件回退到上个版本############################################### 或者执行,达到将暂存内容清空git reset --mixed HEAD #指向当前提交点,其实没回退指针,但会清空暂存。# 然后执行:git checkout --abc.txt ##从版本库中拉取abc.txt文件,恢复当当前版本的原始状态 ( 撤销了所有修改 )
###################### Hard ############################指针后退一步,暂存清空,且将工作区也同步到指针所指的状态git reset --hard HEAD~ # 用于拉取某个特定提交点的文件
提交后发现有问题,比如有些注释忘记修改,比如提交描述不够详细等等。
当然可以修改后,在提交一次,但是还有更好的办法:
git commit --amend -m"xxxxx"
:会再次提交并替换上次提交
转载地址:http://hpgzi.baihongyu.com/