Git的使用

Git作为开发人员的管理工具,使用的最为广泛。从仓库的创建,到分支的创建提交,代码的拉取、合并、rebase,commit压缩简化,前前后后有若干命令,经常使用完毕就忘记,这里将最近常用的命令做一整理以供参考和记忆。

1.Git上的工作区、暂存区介绍

在Git中我们使用 git add 和git rm操作来添加改动到暂存区,并使用git commit来生成一个提交(备份),接下来我们了解添加文件、修改、删除这三种改动添加到暂存区的方法和生成一次提交的方法。

暂存区到底是什么?

我们平时把电脑上的目录叫做工作区,里边是我们实际操作的文件。而暂存区里边一开始会包含上个提交时的所有文件,然后我们会通过git add 、git rm操作来吧工作区里的改动添加到暂存区,比如添加新文件到暂存区,把修改后的文件添加到暂存区以及删除暂存区中的文件。当最后提交时,git把暂存区中的所有文件组织成一课树,再加入时间、作者等信息形成一次commit对象。再把commit对象与上一次提交生成的commit对象链接起来,就完成了一次新的提交。

在新建git仓库后,所有的文件都还没有加入到git版本控制系统中。当前仓库是空的。Git init在当前目录下生成了一个.git目录,这个目录下有一个objects目录,这个目录下的文件才是属于git仓库的。刚刚初始化的objects目录有两个目录,一个是info、一个是pack,刚开始啥也没有,都是空的。 这是对于git来说存在了很多新建的文件,通过git status命令可以查看仓库的状态。其中的Untracked files中的内容就是我们还没添加的改动——添加文件。 

添加文件

上面说的 git status显示的 untracked files 均是在当前版本中还没添加到暂存区的文件,使用git add <file>来讲他们添加到暂存区,在加入之后用git status查看状态。

 Git add 添加后提示 changes to be commited(等待提交的改动),显示是new file,这说明我们将刚刚新建的文件添加到暂存区了。 添加完成后使用git commit -m"添加了Team.java文件" 将暂存区的内从生成一个提交。

修改文件

以上文件添加之后我们对它进行修改,添加一个字段,然后执行git status。

 发现提示 modified xxxxxx 表示这个文件被修改还没添加。执行git add 添加: 

最后再一次执行git commit -m”修改Team.java” 完成使用git log --oneline 查看操作日志:发现添加了两个commit

git status原理 (工作区、暂存区、和上一个提交中的文件区) 在使用git status命令查看仓库状态是,经常会看到Untracked files、Changes not staged commitChanges to be committed三个标题。 这三个标题的内容是根据三个文件树产生的。这三个文件树分别为工作区,暂存区和上一个提交中的文件区(仓库刚刚初始化的时候,没有提交,相当于文件树为空)。Untracked files 显示的是工作区中存在而暂存区中没有的文件。 通常为新疆的文件,而 Changes not staged commit里是工作区中和暂存区内容不同的文件,通常是因为修改了文件的内容,显示为modified,以及暂存区里存在但工作区里没有的文件,通常是因为删除了文件,显示为deleted。而 Changes to be committed 里显示的是暂存区里有,但是上一次提交中没有的内容,等待commit提交。

 2.Git 命令使用

1.创建分支

创建分支 git branch <branch_name>

从指定的服务器创建分支:

实例: 从digua/dev-team上创建一个分支dev-team-1并切换到dev-team-1

git checkout -b dev-team-1 digua/dev-team

如果是默认的则: git checkout -b dev_fix 表示从当前分支上创建一个分支(当前分支在那个远程就是哪个,比如是origin或者zhihu)

2.撤销

1. git restore <FileName> 将文件撤销到上次提交的状态(会丢失这次提交的内容) https://blog.csdn.net/qq_38158479/article/details/106972138 参考 一个文件已经在git管理中了,并且有一些内容。这时候我们添加一些修改。 这个时候文件只是modified状态:

 执行git restore base/src/main/res/layout/base_activity_main.xml 就会抛弃刚刚添加的修改内容,让文件回到之前的状态。(修改内容丢失)

2.一个文件被修改了,然后执行了git add (执行 git status 文件变为绿色的时候),提示执行

git restore --staged <file>来撤销暂存区的保存。 如图: 一个文件已经在git中了,然后又一次修改了并且执行了 git add 文件名称后如下(绿色):

 这时候执行git restore --staged <file> 结果:文件修改的内容不会丢失,只是从add状态撤回到了add之前的状态。 在这之后如果想抛弃之前的修改,可以再一次执行git restore <file> ​​​​​​​

 checkout和restore都可以撤销一个提交到暂存区的文件,使其恢复到上次提交之前(这个操作会丢失掉这次修改的东西)

revert命令(逆转、反转,revert操作到一次commit,不会影响之后的commit) ??? https://blog.csdn.net/yxlshk/article/details/79944535 可以参考的文档 一个修改commit之后如果想撤销,需要使用revert命令,revert 命令会生成一次新的提交并要求填写提交说明,然后把上次的提交撤回。实例如下: 先添加了一次提交,这个commit提交添加了一个name字段和TextView在布局中。 

提交后发现添加错误,这次提交的内容不要,需要撤退: 执行:git revert 提交记录的字符串 

执行后添加了一git 记录。

2.git reset 命令

git reset 命令 将当前的HEAD 重置为指定的状态 reset命令的语法:git reset [--soft | --mixed | --hard ] [HEAD]

1.reset回退命令基础使用 普通的回退当前代码到上一次提交: git reset HEAD^ (对于zsh可能需要转义“^”为“\^”) 实例:使用了git reset HEAD\^回退刚刚的一次提交,执行后代码恢复到暂存区的状态

 执行回退后使用git status查看状态,代码回到了暂存区的状态:

 添加多提提交进行回退(这里添加了三个提交)

 

执行恢复到三次提交前: git reset HEAD~3 

回退结果:日志全部回退到三次之前,三次提交的代码全部保留,状态恢复到暂存区,待提交。

总结:当提交了代码后发现提交有问题,使用git reset HEAD^可以随时回退到上一次的提交状态,并且代码不会丢失。 当提交了多次发现提交有问题,可以使用git reset HEAD~次数 来回退到之前的状态,代码不会丢失,提交记录和日志全部回退。(这里可以发现如果提交了多次,想要合并提交或者修改提交日志,也可以通过回退的方式清除提交记录,重新提交,修改提交日志) 

 2.官方解读

git reset [<mode>] [<commit>] This form resets the current branch head to <commit> and possibly updates the index (resetting it to the tree of <commit>) and the working tree depending on <mode>. If <mode> is omitted, defaults to --mixed. The <mode> must be one of the following:

--soft Does not touch the index file or the working tree at all (but resets the head to <commit>, just like all modes do). This leaves all your changed files "Changes to be committed", as git status would put it.

--mixed Resets the index but not the working tree (i.e., the changed files are preserved but not marked for commit) and reports what has not been updated. This is the default action. If -N is specified, removed paths are marked as intent-to-add (see git- add(1)).

--hard Resets the index and working tree. Any changes to tracked files in the working tree since <commit> are discarded.

--merge Resets the index and updates the files in the working tree that are different between <commit> and HEAD, but keeps those which are different between the index and working tree (i.e. which have changes which have not been added). If a file that is different between <commit> and the index has unstaged changes, reset is aborted.

3.其他使用方式

实例1: git reset 64a2072eddcca7fb35b45cf2b1e6ca66c46ec79 将当前的提交回退到64a2072eddcca7fb35b45cf2b1e6ca66c46ec79指定的版本。 默认情况git reset使用的是mixed,用于重置暂存区的文件,工作区的保持不变,也就是上次的修改会保丢,不会丢失。 git的提交记录log会回退。  

实例2: reset之前先提交一个修改:

  

执行reset命令:git reset --soft xxxxxxxxxxx 执行后代码从回到暂存区,代码依然保留,提交日志回到之前的状态

实例3 使用 git reset --hard参数

执行git reset --hard HEAD~2   (HEAD~2 表示向后回退两个提交),结果如下: 

执行完毕向后回退了两个提交,之前的提交日志和代码都回退了没有了任何之前的提交记录。

reset和revert命令的以上操作都在在本地。本地reset操作完成正常push远程会提示我们有代码更新。因为这时候远程的代码还没有回滚,远程的提交比本地的多,提示我们更新远程的代码。如果我们要远程的代码也回滚,需要强制提交到远程,实例如下: git push origin master -f

https://blog.csdn.net/lovesummerforever/article/details/71526900 参考

restore、reset和revert三者的区别

  1. restore命令在commit之前操作,如果文件没有执行git add,则使用git restore<file>这个操作会抛弃之前的修改。如果文件被修改并且执行了git add <file>(执行git status文件成了绿色)这个时候执行git restore --staged<file>把文件从暂存区移除。
  2. reset在commit之后操作: reset的mixed和soft操作都会让之前的commit回退到指定的提交,提交日志丢失,但是文件的修改内容依然存在。 reset的hard参数会让之前的commit回退到指定的提交,提交日志和文件内容的修改都会丢失(这是一个危险的操作,内容会丢失)
  3. revert命令 ???? reset是回朔到指定的commit版本,指定的commit版本之后的操作commit都重置了。revert是删除指定的commit操作的内容,指定的commit之前和之后commit操作都不受影响,与此同时这个操作也会作为一个commit进行提交。 git reset 是把HEAD向后移动了一下,而git revert是HEAD继续前进,只是新的commit的内容和要revert的内容正好相反,能够抵消要被revert的内容 

 4.git查看历史操作和日志 git查看历史操作记录

1.查看历史操作记录 git reflog

2.单行显示操作log git log --oneline  一行显示日志

3.git log --stat 可以显示简化的提交历史的log git log -n 显示出最近 n 提交的历史 比如和git log --stat -2 一起使用,显示出最近2次提交的历史记录

5.git diff 命令

若要查看已暂存的将要添加到下次提交里的内容,可以用 git diff --staged 命令。 这条命令将比对已暂存文件与最后一次提交的文件差异 请注意,git diff 本身只显示尚未暂存的改动,而不是自上次提交以来所做的所有改动。 所以有时候你一下子暂存了所有更新过的文件,运行 git diff 后却什么也没有,就是这个原因。 然后用 git diff --cached 查看已经暂存(add后的)起来的变化( --staged 和 --cached 是同义词) 

6.暂存当前的修改

暂存当前分支的修改用git stash

git stash pop 将暂存从暂存的栈出栈,清除这次保存记录

git stash apply 将暂存从暂存栈出栈,暂存记录依然保留 git stash listh 可以查看 暂存的记录

7.移除(删除)文件

将一个文件从git管理移除 git rm --cached 文件名 实例: git rm --cached pubspec.lock 

 移除文件:

1.git命令从git缓存中移除管理的文件

参考 https://git-scm.com/book/zh/v2/Git-%E5%9F%BA%E7%A1%80-%E8%AE%B0%E5%BD%95%E6%AF%8F%E6%AC%A1%E6%9B%B4%E6%96%B0%E5%88%B0%E4%BB%93%E5%BA%93

git rm --cached README 我们想把文件从 Git 仓库中删除(亦即从暂存区域移除),但仍然希望保留在当前工作目录中。 换句话说,你想让文件保留在磁盘,但是并不想让 Git 继续跟踪。 当你忘记添加 .gitignore 文件,不小心把一个很大的日志文件或一堆 .a 这样的编译生成文件添加到暂存区时,这一做法尤其有用。 为达到这一目的,使用 --cached 选项 .

2.从工作区移除(删掉文件)

要从git中移除某个文件,就必须要从已经跟踪的文件清单中移除(确切的说是从暂存区移除),然后提交。可以使用git rm命令完成此项工作,并且连带从工作目录中删除指定的文件,这样以后就不会出现在未跟踪文件清单中了

 7.撤销修改

git checkout -- FileName git checkout -- <file> 是一个危险的命令。 你对那个文件在本地的任何修改都会消失——Git 会用最近提交的版本覆盖掉它(把工作区的使用暂存区的文件覆盖) git reset HEAD <file> git是把暂存区里的文件用上一次提交的文件代替

8.git fetch拉取代码命令(git pull 命令)

从远程服务器拉取代码 git fetch origin  拉取所有origin上的代码 git fetch origin master 拉取origin上的master分支的代码 官网实例: 

拉取完毕 使用git merge <要被合并代码的的分支名称> 合并 比如:

git checkout master  先切换到master分支

git merge develop  然后把develop分支上拉的代码合并到master上 (合并时,如果有多个远程可能需要指定origin如git merge origin/develop)

https://git-scm.com/book/zh/v2/Git-%E5%88%86%E6%94%AF-%E5%88%86%E6%94%AF%E7%9A%84%E6%96%B0%E5%BB%BA%E4%B8%8E%E5%90%88%E5%B9%B6  

10.git合并流程(公司项目合并流程)

官网介绍: git checkuot -b sf origin/serverfix 现在,本地分支sf会自动从origin/serverfix拉取。 设置已有本地分支跟踪一个刚刚拉取下来的远程分支,或者想要修改正在跟踪的上游分支,可以在任意时间使用 -u 或者--set-upstream-to选项运行git branch 来显示的设置。

如:git branch -u origin/serverfix。 当上游设置好跟踪分支后,可以通过简写@{upstream}或@{u}来引用它的上游分支。所以在master分支时并且它正在跟踪origin/master时,如果愿意可以使用git merge @{u}来取代 git merge origin/master

 官网的普通合并实例:

 公司的项目合并:

公司的git管理采用fork的形式,fork到个人的git,通过设置两个远程服务器地址和主项目保持一致。因此在操作拉取代码,提交到远程服务器的时候要指定一个远程名称,比如指定「origin」 或者 「digua」,origin或者digua只是远程服务的一个名字。 这个名字在添加远程服务地址的时候指定:

如:(表示添加一个自己(zhangsan)从主工程fork来的地址,名称为origin)

git remote add origin git@git.digua.com:zhangsan/diguaApp.git 或者:

git remote add digua git@git.in.digua.com:XXX/diguaApp.git 表示添加一个主工程的远程地址,名字叫digua. 以上如果远程主工程有了更新,我们首先拉取代码: git fetch digua

然后在自己的开发分支上合并代码

git checkout dev_fix (切换到自己的分支dev_fix)

git merge digua/dev   (合并来自远程digau地址的代码到dev_fix分支)

 当一个修改branch开发完毕后先push到自己的远程仓库,然后通过提merge request来发起代码合并。 git push origin  (自己的远程仓库名称是『origin』、公司的叫『digua』) 提交填写表单发起合并请求

11.git使用merge合并

1.普通merge合并 通常我们在一个分支上开发完成一部分功能,需要合并到另外一个分支上,比如我们有一个主分支master,现在在一个开发分支fix上做了一些开发,最后要合并到master上,则操作如下:

首先切换到master分支 Git checkout master 然后合并:

git merge fix (使用merge的时候注意是谁合并到谁上,首先切换到要合并其他分支代码的分支上,然后git merge <要被合并的branch 名称>) 

 git上的合并通常叫做三方合并。合并时会确定三个提交,当前分支对应的提交,被合并分支对应的提交,和两个要合并分支的共同祖先提交。Git会把其他两个相对于共同祖先提交的改动提取出来,如果这份改动里对同一个文件进行了修改,那么git会提示自动合并失败,让我们手动修改冲突的文件,在修改完成后,使用git commit 把所有改动提交,如果没有对同一个文件进行改动,git就会帮我们添加所有改动到新的提交中。(注意使用merge合并,git会自动提取相同的祖先然后再生成一次commit作为合并的提交)

注意有一个特殊情况: 我们从一个提交创建一个分支比如从master上创建了一个fix,现在只在fix上修改提交,master这个分支没有改动。那么当fix修改完毕需要合并到master上的时候就不会在提取共同的祖先生成一个新的合并提交了,而是直接把master分支的指针指向fix所在提交的当前提交。这种简化的合并模式叫做——快进(fast-forward)(git终端会提示fast-forward合并成功。)

如果我们不想使用fast-forward模式合并,想保存工作轨迹,那么我们在合并的时候使用--no-ff来关闭快进模式。

如:git merge --no-off <要被合并的分支名称> -m”注释文字”

合并取消

合并别人提交的代码的时候如果出现了conflicts,可能要修改很多,此时如果想取消这次合并可以使用git merge --abort

git merge --abort 如果你尝试合并两个分支,随后遇到了合并冲突,运行 git mergetool,Git 会调用 P4Merge 让你通过图形界面来解决冲突(如果已经安装设置了P4Merge )。如果使用类似Android studio,这些工具自带合并的可视化操作,直接点击对应的操作按钮即可

 2.git merge --squash <branch_name> 压缩提交合并

很多时候,我们会把一个功能的实现分为好几个功能点,然后给功能点新建一条分支,然后在这个功能点开发完毕后把修改整合回功能分支。这样做的好处是功能分支整洁,不会在功能分支上备份代码提交。但是如果用merge合并的话,合并成的提交除了指向主功能分支外,也会指向功能点分支,那样还是会把功能点分支的提交历史混进来。

这时候我们可以使用git merge --squash <branch_name>,在merge指令中添加一个--squash 后会把branch_name分支上的所有提交压缩成一个加入上当前分支上来。并且这个提交不会指向合并的分支。

合并结果如图:下面的feature-CloaseDoorwithGesture没有指向producerDoor

 在合并完成没有问题后,我们就可以删除feature-CloaseDoorwithGesture分支。

实例: squash 压缩合并 https://blog.csdn.net/sxh951026/article/details/77200003 参考文章最后部分

12.git rebase命令

1.rebase的作用 

使用 git rebase -i 命令整理提交记录 一般我们会给每个功能新建一个分支,在功能开发完成后,可以使用 git rebase -i 命令删去哪些无关紧要的提交,并将提交历史修改成我们想要的样子。

如某个分支合并前的样子:由于修改多次,有很多的细小的commit,我们可以把它合并一下 

比如把处理图片的合并到一起。

在命令行输入:git rebase -i b966633 来修改,输入后界面入下: 

在最前面的是各个提交,每个提交的前面是要对该提交执行的命令,默认是 pick 采用提交。我们主要用到 squash 命令,squash 命令可以让我们把对应的提交合并到上一次提交中。

举例:这里我们把41130b9squash 对应的修改为则会把它合并到89f928b上。 

修改后退出编辑框会弹出提示,让修改提交记录

 修改一下再退出:提示rebase合并成功

再一次查看日志如下:

我们之前的两个有关图片的提交记录已经被合并成了一条.简化了提交记录。

参考:

https://blog.csdn.net/sxh951026/article/details/77200003

https://juejin.cn/post/6844903600976576519 

以上为最近用到了一些命令和操作,做以记录,对于整个git的使用流程还有很多缺少的地方,待后续用到在加以补充。

参考资料

完整git操作流程参考,从git创建到rebase的使用

https://blog.csdn.net/sxh951026/article/details/77200003

官网文档

https://git-scm.com/docs

https://git-scm.com/book/zh/v2

使用rebase合并多条提交记录

https://juejin.cn/post/6844903600976576519

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值