Git07

提交

通过add只是将文件或目录添加到了index暂存区,使用commit可以实现将暂存区的文件提交到本地仓库。

复制代码
# 提交暂存区到仓库区
$ git commit -m [message]

# 提交暂存区的指定文件到仓库区
$ git commit [file1] [file2] ... -m [message]

# 提交工作区自上次commit之后的变化,直接到仓库区,跳过了add,对新文件无效
$ git commit -a

# 提交时显示所有diff信息
$ git commit -v

# 使用一次新的commit,替代上一次提交
# 如果代码没有任何新变化,则用来改写上一次commit的提交信息
$ git commit --amend -m [message]

# 重做上一次commit,并包括指定文件的新变化
$ git commit --amend [file1] [file2] ...
复制代码

示例:

提交前的状态

提交:

提交后的状态:

从上图中可以看出暂存区中没有了bar.htm

修订提交

如果我们提交过后发现有个文件改错了,或者只是想修改提交说明,这时可以对相应文件做出修改,将修改过的文件通过"git add"添加到暂存区,然后执行以下命令:

#修订提交
git commit --amend

撤销提交(commit)

原理就是放弃工作区和index的改动,同时HEAD指针指向前一个commit对象

#撤销上一次的提交
git reset --hard HEAD~1

 要通过git log查看提交日志,也可直接指定提交编号或序号

示例:

撤销提交
git revert <commit-id>
这条命令会把指定的提交的所有修改回滚,并同时生成一个新的提交。

4.3.8、日志与历史

查看提交日志可以使用git log指令,语法格式如下:

#查看提交日志
git log [<options>] [<revision range>] [[--] <path>…?]

示例:

"git log --graph"以图形化的方式显示提交历史的关系,这就可以方便地查看提交历史的分支信息,当然是控制台用字符画出来的图形。

"git log -1"则表示显示1行。

使用history可以查看您在bash下输入过的指令:

几乎所有输入过的都被记录下来的,不愧是做版本控制的。

查看所有分支日志

"git reflog"中会记录这个仓库中所有的分支的所有更新记录,包括已经撤销的更新。

4.3.9、查看文件列表

使用git ls-files指令可以查看指定状态的文件列表,格式如下:

#查看指定状态的文件
git ls-files [-z] [-t] [-v] (--[cached|deleted|others|ignored|stage|unmerged|killed|modified])* (-[c|d|o|i|s|u|k|m])*

示例:

4.3.10、撤销更新

1)、撤销暂存区更新

使用"git add"把更新提交到了暂存区。这时"git status"的输出中提示我们可以通过"git reset HEAD <file>..."把暂存区的更新移出到WorkSpace中

示例:f6已经提交,工作区修改,暂存区修改,撤销

2)、撤销本地仓库更新

使用git log查看提交日志

撤销提交有两种方式:使用HEAD指针使用commit id

在Git中,有一个HEAD指针指向当前分支中最新的提交。当前版本,我们使用"HEAD^",那么再钱一个版本可以使用"HEAD^^",如果想回退到更早的提交,可以使用"HEAD~n"。(也就是,HEAD^=HEAD~1,HEAD^^=HEAD~2)

git reset --hard HEAD^
git reset --hard HEAD~1
git reset --59cf9334cf957535cb328f22a1579b84db0911e5

示例:回退到添加f6

回退前:

回退后:

 

现在又想恢复被撤销的提交可用"git reflog"查看仓库中所有的分支的所有更新记录,包括已经撤销的更新,撤销方法与前面一样。

git reset --hard HEAD@{7}
git reset --hard e0e79d7

--hard:撤销并删除相应的更新

--soft:撤销相应的更新,把这些更新的内容放到Stage中

4.3.11、删除文件

1)、删除未跟踪文件

如果文件还是未跟踪状态,直接删除文件就可了,bash中使用rm可以删除文件,示例如下:

2)、删除已提交文件

 

-f 强制删除,物理删除了,同时删除工作区和暂存区中的文件

撤销删除:

#to discard changes in working directory
git checkout -- <file>...

3)、删除暂存区的文件,不删除工作区的文件

 

使用git reset HEAD <file>...同样可以实现上面的功能

4.3.12、文件操作小结

 Git很强大,很灵活,这是毋庸置疑的。但也正因为它的强大造成了它的复杂,因此会有很多奇奇怪怪的问题出现,多用就好了。

4.4、GIT分支

分支在GIT中相对较难

分支就是科幻电影里面的平行宇宙,当你正在电脑前努力学习Git的时候,另一个你正在另一个平行宇宙里努力学习SVN。

如果两个平行宇宙互不干扰,那对现在的你也没啥影响。不过,在某个时间点,两个平行宇宙合并了,结果,你既学会了Git又学会了SVN!

分支在实际中有什么用呢?假设你准备开发一个新功能,但是需要两周才能完成,第一周你写了50%的代码,如果立刻提交,由于代码还没写完,不完整的代码库会导致别人不能干活了。如果等代码全部写完再一次提交,又存在丢失每天进度的巨大风险。

现在有了分支,就不用怕了。你创建了一个属于你自己的分支,别人看不到,还继续在原来的分支上正常工作,而你在自己的分支上干活,想提交就提交,直到开发完毕后,再一次性合并到原来的分支上,这样,既安全,又不影响别人工作。

Git分支的速度非常快。

截止到目前,只有一条时间线,在Git里,这个分支叫主分支,即master分支。HEAD严格来说不是指向提交,而是指向master,master才是指向提交的,所以,HEAD指向的就是当前分支。

特性分支的图示

git分支中常用指令:

复制代码
# 列出所有本地分支
$ git branch

# 列出所有远程分支
$ git branch -r

# 列出所有本地分支和远程分支
$ git branch -a

# 新建一个分支,但依然停留在当前分支
$ git branch [branch-name]

# 新建一个分支,并切换到该分支
$ git checkout -b [branch]

# 新建一个分支,指向指定commit
$ git branch [branch] [commit]

# 新建一个分支,与指定的远程分支建立追踪关系
$ git branch --track [branch] [remote-branch]

# 切换到指定分支,并更新工作区
$ git checkout [branch-name]

# 切换到上一个分支
$ git checkout -

# 建立追踪关系,在现有分支与指定的远程分支之间
$ git branch --set-upstream [branch] [remote-branch]

# 合并指定分支到当前分支
$ git merge [branch]

# 选择一个commit,合并进当前分支
$ git cherry-pick [commit]

# 删除分支
$ git branch -d [branch-name]

# 删除远程分支
$ git push origin --delete [branch-name]
$ git branch -dr [remote/branch]
复制代码

4.4.1、新建分支与切换分支

每次提交,Git都把它们串成一条时间线,这条时间线就是一个分支。截止到目前,只有一条时间线,在Git里,这个分支叫主分支,即master分支。HEAD严格来说不是指向提交,而是指向master,master才是指向提交的,所以,HEAD指向的就是当前分支。
一开始的时候,master分支是一条线,Git用master指向最新的提交,再用HEAD指向master,就能确定当前分支,以及当前分支的提交点:

每次提交,master分支都会向前移动一步,这样,随着你不断提交,master分支的线也越来越长:

默认分支是这样的,master是主分支

git-br-initial

1)、新建一个分支,但依然停留在当前分支,使用:$ git branch [branch-name]

切换分支到dev1后的结果:

关于分支廖雪峰解释的比较清楚,我们引用一下

当我们创建新的分支,例如dev时,Git新建了一个指针叫dev,指向master相同的提交,再把HEAD指向dev,就表示当前分支在dev上:

git-br-create

你看,Git创建一个分支很快,因为除了增加一个dev指针,改改HEAD的指向,工作区的文件都没有任何变化!

不过,从现在开始,对工作区的修改和提交就是针对dev分支了,比如新提交一次后,dev指针往前移动一步,而master指针不变:

git-br-dev-fd

假如我们在dev上的工作完成了,就可以把dev合并到master上。Git怎么合并呢?最简单的方法,就是直接把master指向dev的当前提交,就完成了合并:

git-br-ff-merge

所以Git合并分支也很快!就改改指针,工作区内容也不变!

合并完分支后,甚至可以删除dev分支。删除dev分支就是把dev指针给删掉,删掉后,我们就剩下了一条master分支:

git-br-rm

动画演示:

2)、切换分支,git branch <name>,如果name为-则为上一个分支

切换为上一个分支

3)、新建一个分支,并切换到该分支,$ git checkout -b [branch]

4)、新建一个分支,指向指定commit使用命令:$ git branch [branch] [commit]

 

上面创建了dev3分支且指向了master中首次提交的位置,切换到dev3查看日志如下:

master上本来有两个提交记录的,此时的dev3指向的是第1次提交的位置

 5)、新建一个分支,与指定的远程分支建立追踪关系使用命令:$ git branch --track [branch] [remote-branch]

4.4.2、查看分支

1)、列出所有本地分支使用$ git branch

2)、列表所有远程分支使用$ git branch -r

3)、列出所有本地分支和远程分支使用$ git branch -a

4.4.3、分支合并

合并指定分支到当前分支使用指令$ git merge [branch]

这里的合并分支就是对分支的指针操作,我们先创建一个分支再合并到主分支:

这里的file11.txt主分支与dev6的内容现在是不同的,因为在dev6中已被修改过,我们可以使用指令查看:

现在我们将dev6合并到主分支中去,从下图中可以看出dev6中有一次提交,而master并没有

合并后在master上查看file11.txt文件内容与dev6上的内容就一样了,合并后dev6中多出的提交在master也拥有了。

4.4.4、解决冲突

如果同一个文件在合并分支时都被修改了则会引起冲突,如下所示:

提交前两个分支的状态

在dev6分支中同样修改file11.txt

dev6与master分支中file11.txt文件都被修改且提交了,现在合并分支

提示冲突,现在我们看看file11.txt在master分支中的状态

Git用<<<<<<<,=======,>>>>>>>标记出不同分支的内容,其中<<<HEAD是指主分支修改的内容,>>>>>dev6 是指dev6上修改的内容

解决的办法是我们可以修改冲突文件后重新提交,请注意当前的状态产master | MERGING:

重新提交后冲突解决:

手动解决完冲突后就可以把此文件添 加到索引(index)中去,用git commit命令来提交,就像平时修改了一个文件 一样。

git log --graph命令可以看到分支合并图。

分支策略

master主分支应该非常稳定,用来发布新版本,一般情况下不允许在上面工作,工作一般情况下在新建的dev分支上工作,工作完后,比如上要发布,或者说dev分支代码稳定后可以合并到主分支master上来。

4.4.5、删除分支

删除本地分支可以使用命令:$ git branch -d [branch-name],-D(大写)强制删除

删除远程分支可以使用如下指令:

$ git push origin --delete [branch-name]
$ git branch -dr [remote/branch]

-d表示删除分支。分支必须完全合并在其上游分支,或者在HEAD上没有设置上游

-r表示远程的意思remotes,如果-dr则表示删除远程分支

4.5、Git GUI 操作

通过命令行可以深刻的理解Git,Git GUI或IDE插件却可以更加直观操作Git,常用的Git GUI有如下这些:

4.5.1、GitHub for Desktop

全球开发人员交友俱乐部提供的强大工具,功能完善,使用方便。对于使用GitHub的开发人员来说是非常便捷的工具。

GitHub for Desktop不带三方合并工具,你必须自己手动解决冲突才可以。

– 免费
– 同时支持 Windows 和 Mac:对于需要经常在不同的操作系统间切换的开发人员来说非常方便。
– 漂亮的界面:作为每天盯着看的工具,颜值是非常重要的
– 支持Pull Request:直接从客户端提交PR,很方便
– Timeline 支持:直接在时间线上显示每次提交的时间点和大小
– 支持git LFS:存储大文件更加节省空间和高效
– 不支持三方合并:需要借助第三方工具才行

原文地址:https://www.cnblogs.com/huaobin/p/14910275.html