实际开发中完整的git操作流程

一、获取 Git 仓库

有两种取得 Git 项目仓库的方法。
第一种是在现有项目或目录下导入所有文件到 Git 中;
第二种是从一个服务器克隆一个现有的 Git 仓库。

1、在现有目录中初始化仓库

如果你打算使用 Git 来对现有的项目进行管理,你只需要进入该项目目录并输入:
$ git init
该命令将创建一个名为 .git 的子目录,这个子目录含有你初始化的 Git 仓库中所有的必须文件,这些文件是Git 仓库的骨干。

2、克隆现有的仓库

如果你想获得一份已经存在了的 Git 仓库的拷贝,比如说,你想为某个开源项目贡献自己的一份力,这时就要用到 git clone 命令。

克隆仓库的命令格式是 git clone [url] 。 比如,要克隆 Git 的可链接库 libgit2,可以用下面的命令:

$ git clone https://github.com/libgit2/libgit2

这会在当前目录下创建一个名为 “libgit2” 的目录,并在这个目录下初始化一个 .git 文件夹,从远程仓库拉取下所有数据放入 .git 文件夹,然后从中读取最新版本的文件的拷贝。

如果你想在克隆远程仓库的 时候,自定义本地仓库的名字,你可以使用如下命令:

$ git clone https://github.com/libgit2/libgit2 mylibgit

这将执行与上一个命令相同的操作,不过在本地创建的仓库名字变为 mylibgit。

3、实际操作

在这里插入图片描述
文件夹显示
在这里插入图片描述

二、记录每次更新到仓库

工作目录下的每一个文件都不外乎这两种状态:已跟踪或未跟踪
已跟踪的文件是指那些被纳入了版本控制的文件,在上一次快照中有它们的记录,在工作一段时间后,它们的状态可能处于未修改,已修改或已放入暂存区。 工作目录中除已跟踪文件以外的所有其它文件都属于未跟踪文件,它们既不存在于上次快照的记 录中,也没有放入暂存区。 初次克隆某个仓库的时候,工作目录中的所有文件都属于已跟踪文件,并处于未修 改状态。

1、检查当前文件状态

要查看哪些文件处于什么状态,可以用 git status 命令。
在这里插入图片描述
这说明你现在的工作目录相当干净。换句话说,所有已跟踪文件在上次提交后都未被更改过。 此外,上面的信息还表明,当前目录下没有出现任何处于未跟踪状态的新文件,否则 Git 会在这里列出来。 最后,该命令还显示了当前所在分支,并告诉你这个分支同远程服务器上对应的分支没有偏离。

现在,让我们在项目下创建一个新的 afei.html 文件。 如果之前并不存在这个文件,使用 git status 命令,你将看到一个新的未跟踪文件:
在这里插入图片描述
在这里插入图片描述
在状态报告中可以看到新建的 afei.html文件出现在 Untracked files 下面。 未跟踪的文件意味着 Git 在之前的快照(提交)中没有这些文件;

2、跟踪新文件

使用命令 git add 开始跟踪一个文件。 所以,要跟踪 afei.html 文件,运行:

$ git add afei.html

此时再运行 git status 命令,会看到afei.html 文件已被跟踪,并处于暂存状态:
在这里插入图片描述

3、暂存已修改文件

现在我们来修改一个已被跟踪的文件。 如果你修改了一个名为 README.md 的已被跟踪的文件,然后运行 git status 命令,会看到下面内容:
在这里插入图片描述
文件 README.md 出现在 Changes not staged for commit 这行下面,说明已跟踪文件的内容发
生了变化,但还没有放到暂存区。 要暂存这次更新,需要运行 git add 命令。
在这里插入图片描述
现在两个文件都已暂存,下次提交时就会一并记录到仓库。假设此时,你想要在 README.md 里再加条 注释, 重新编辑存盘后,准备好提交。 不过且慢,再运行 git status 看看:
在这里插入图片描述
怎么回事? 现在 README.md 文件同时出现在暂存区和非暂存区。 这怎么可能呢? 好吧,实际上 Git 只不过暂存了你运行 git add 命令时的版本, 如果你现在提交,README.md 的版本是你最后一次运行
git add 命令时的那个版本,而不是你运行 git commit 时,在工作目录中的当前版本。 所以,运行了 git
add 之后又作了修订的文件,需要重新运行 git add 把最新版本重新暂存起来:
在这里插入图片描述

4、查看已暂存和未暂存的修改

如果 git status 命令的输出对于你来说过于模糊,你想知道具体修改了什么地方,可以用 git diff 命令。
假如再次修改 README 文件后暂存,然后编辑 afei.html 文件后先不暂存, 运行 status 命令将会看到:
在这里插入图片描述
要查看尚未暂存的文件更新了哪些部分,不加参数直接输入 git diff
在这里插入图片描述
若要查看已暂存的将要添加到下次提交里的内容,可以用 git diff --cached 命令。
在这里插入图片描述

请注意,git diff 本身只显示尚未暂存的改动,而不是自上次提交以来所做的所有改动。 所以有时候你一下子暂 存了所有更新过的文件后,运行 git diff 后却什么也没有,就是这个原因。

5、提交更新

现在的暂存区域已经准备妥当可以提交了。 在此之前,请一定要确认还有什么修改过的或新建的文件还没有git add 过,否则提交的时候不会记录这些还没暂存起来的变化。 这些修改过的文件只保留在本地磁盘。 所以,每次准备提交前,先用 git status 看下,是不是都已暂存起来了, 然后再运行提交命令 git commit
在这里插入图片描述

可以看到此时,我们修改的afei.html文件还未放到暂存区,因此我们将其放入进去,再提交
在这里插入图片描述
接下来提交

$ git commit -m "备注"

在这里插入图片描述

6、移除文件

要从 Git 中移除某个文件,就必须要从已跟踪文件清单中移除(确切地说,是从暂存区域移除),然后提交。 可以用 git rm 命令完成此项工作,并连带从工作目录中删除指定的文件,这样以后就不会出现在未跟踪文件清 单中了。
假设现在再新添加一个afei2.html文件
在这里插入图片描述
将其放入暂存区
在这里插入图片描述
现在将afei2.html移除
在这里插入图片描述
下一次提交时,该文件就不再纳入版本管理了。 如果删除之前修改过并且已经放到暂存区域的话,则必须要用强制删除选项 -f

7、查看提交历史

在提交了若干更新,又或者克隆了某个项目之后,你也许想回顾下提交历史。 完成这个任务最简单而又有效的工具是 git log 命令。
在这里插入图片描述
git log 有许多选项可以帮助你搜寻你所要找的提交, 接下来我们介绍些最常用的。
一个常用的选项是 -p,用来显示每次提交的内容差异。 你也可以加上 -2 来仅显示最近两次提交:
在这里插入图片描述

8、撤消操作

在任何一个阶段,你都有可能想要撤消某些操作。 这里,我们将会学习几个撤消你所做修改的基本工具。 注意,有些撤消操作是不可逆的。 这是在使用 Git 的过程中,会因为操作失误而导致之前的工作丢失的少有的几个地方之一。
有时候我们提交完了才发现漏掉了几个文件没有添加,或者提交信息写错了。 此时,可以运行带有 - -amend 选项的提交命令尝试重新提交:

$ git commit --amend

在这里插入图片描述
或者现在发现有一个文件在暂存区,但是忘记提交了
在这里插入图片描述
最终你只会有一个提交 - 第二次提交将代替第一次提交的结果。

9、取消暂存的文件

例如,你已经修改了两个文件并且想要将它们作为两次独立的修改提交,但是却意外地输 入了 git add * 暂存了它们两个。 如何只取消暂存两个中的一个呢? git status 命令提示了你:
在这里插入图片描述
我们可以使用git reset HEAD <file>来取消暂存
在这里插入图片描述

10、撤消对文件的修改

如果你并不想保留对 afei2.html 文件的修改怎么办? 你该如何方便地撤消修改 - 将它还原成上次提交
时的样子(或者刚克隆完的样子,或者刚把它放入工作目录时的样子)? 幸运的是,git status 也告诉了你应该如何做。 在最后一个例子中,未暂存区域是这样:
在这里插入图片描述
我们可以使用

$ git checkout -- afei2.html

进行取消修改
在这里插入图片描述
可以看到那些修改已经被撤消了。
你需要知道 git checkout – [file] 是一个危险的命令,这很重要。 你对那个文件做的任何修改都会消失 - 你只是拷贝了另一个文件来覆盖它。 除非你确实清楚不想要那个文件了,否则不要使用这个命令。

三、远程仓库的使用

为了能在任意 Git 项目上协作,你需要知道如何管理自己的远程仓库。 远程仓库是指托管在因特网或其他网络中 的你的项目的版本库。 你可以有好几个远程仓库,通常有些仓库对你只读,有些则可以读写。 与他人协作涉及管理远程仓库以及根据需要推送或拉取数据。 管理远程仓库包括了解如何添加远程仓库、移除无效的远程仓库、管理不同的远程分支并定义它们是否被跟踪等等。

1、查看远程仓库

如果想查看你已经配置的远程仓库服务器,可以运行 git remote 命令。 它会列出你指定的每一个远程服务器的简写。 如果你已经克隆了自己的仓库,那么至少应该能看到 origin - 这是 Git 给你克隆的仓库服务器的默认名 字:
在这里插入图片描述
你也可以指定选项 -v,会显示需要读写远程仓库使用的 Git 保存的简写与其对应的 URL。
在这里插入图片描述
如果你的远程仓库不止一个,该命令会将它们全部列出。

2、添加远程仓库

git remote add <shortname> <url>

在这里插入图片描述
现在你可以在命令行中使用字符串 af 来代替整个 URL。 例如,如果你想拉取 Paul 的仓库中有但你没有的信息,可以运行 git fetch af:
在这里插入图片描述

3、从远程仓库中抓取与拉取

$ git fetch [remote-name]

这个命令会访问远程仓库,从中拉取所有你还没有的数据。 执行完成后,你将会拥有那个远程仓库中所有分支 的引用,可以随时合并或查看。

如果你使用 clone 命令克隆了一个仓库,命令会自动将其添加为远程仓库并默认以 “origin” 为简写。 所以,git fetch origin 会抓取克隆(或上一次抓取)后新推送的所有工作必须注意 git fetch 命令会将数据拉取到你的本地仓库 - 它并不会自动合并或修改你当前的工作。 当准备好时你必须手动将其合并入你的工作。

如果你有一个分支设置为跟踪一个远程分支(阅读下一节与 Git 分支 了解更多信息),可以使用 git pull 命令来自动的抓取然后合并远程分支到当前分支。 这对你来说可能是一个更简单或更舒服的工作流程;默认情况下,git clone 命令会自动设置本地 master 分支跟踪克隆的远程仓库的 master 分支(或不管是什么名字的默认分支)。 运行 git pull 通常会从最初克隆的服务器上抓取数据并自动尝试合并到当前所在的分支。

4、推送到远程仓库

当你想分享你的项目时,必须将其推送到上游。 这个命令很简单:
git push [remote-name][branch-name]
当你想要将 master 分支推送到 origin 服务器时(再次说明,克隆时通常会自动帮你设置好那两个 名字),那么运行这个命令就可以将你所做的备份到服务器:

$ git push origin master

只有当你有所克隆服务器的写入权限,并且之前没有人推送过时,这条命令才能生效。 当你和其他人在同一时间克隆,他们先推送到上游然后你再推送到上游,你的推送就会毫无疑问地被拒绝。 你必须先将他们的工作拉取下来并将其合并进你的工作后才能推送。
在这里插入图片描述
可以看到git远程仓库已经发生变化
在这里插入图片描述

5、查看远程仓库

如果想要查看某一个远程仓库的更多信息,可以使用 git remote show [remote-name] 命令。
在这里插入图片描述
它同样会列出远程仓库的 URL 与跟踪分支的信息。 这些信息非常有用,它告诉你正处于 master 分支,并且如果运行 git pull,就会抓取所有的远程引用,然后将远程 master 分支合并到本地 master 分支。 它也会列出拉取到的所有远程引用。

6、远程仓库的移除与重命名

如果想要重命名引用的名字可以运行 git remote rename 去修改一个远程仓库的简写名。 例如,想要将 af重命名为 origin1,可以用 git remote rename 这样做:
在这里插入图片描述
值得注意的是这同样也会修改你的远程分支名字。 那些过去引用 af/master 的现在会引用 origin1/master。
如果因为一些原因想要移除一个远程仓库 - 你已经从服务器上搬走了或不再想使用某一个特定的镜像了,又或者 某一个贡献者不再贡献了 - 可以使用 git remote rm
在这里插入图片描述

四、Git 分支

1、分支简介

Git 的分支,其实本质上仅仅是指向提交对象的可变指针。 Git 的默认分支名字是 master。 在多次提交操作之后,你其实已经有一个指向最后那个提交对象的 master 分支。 它会在每次的提交操作中自动向前移动。

2、分支创建

Git 是怎么创建新分支的呢? 很简单,它只是为你创建了一个可以移动的新的指针。 比如,创建一个 testing 分支, 你需要使用 git branch 命令:

$ git branch testing

那么,Git 又是怎么知道当前在哪一个分支上呢? 也很简单,它有一个名为 HEAD 的特殊指针。 在 Git 中,它是一个指 针,指向当前所在的本地分支(译注:将 HEAD 想象为当前分支的别名)。 在本例中,你仍然在 master 分支上。 因为 git branch 命令仅仅 创建 一个新分支,并不会自动切换到新分支中去
你可以简单地使用 git log 命令查看各个分支当前所指的对象。 提供这一功能的参数是 --decorate。
在这里插入图片描述
正如你所见,当前 “master” 和 “testing” 分支均指向校验和以203ba60 开头的提交对象。

3、分支切换

要切换到一个已存在的分支,你需要使用 git checkout 命令。 我们现在切换到新创建的 testing 分支 去:

$ git checkout testing

在这里插入图片描述
这样 HEAD 就指向 testing 分支了。
那么,这样的实现方式会给我们带来什么好处呢? 现在不妨再提交一次:
在这里插入图片描述
此时,你的 testing 分支向前移动了,但是 master 分支却没有,它仍然指向运行 git checkout 时所
指的对象。 这就有意思了,现在我们切换回 master 分支看看:

$ git checkout master

这条命令做了两件事。 一是使 HEAD 指回 master 分支,二是将工作目录恢复成 master 分支所指向的快照内容。 也就是说,你现在做修改的话,项目将始于一个较旧的版本。 本质上来讲,这就是忽略 testing 分支所做 的修改,以便于向另一个方向进行开发。
我们不妨再稍微做些修改并提交:
在这里插入图片描述
现在,这个项目的提交历史已经产生了分叉(参见 项目分叉历史)。 因为刚才你创建了一个新分支,并切换过去进行了一些工作,随后又切换回 master 分支进行了另外一些工作。 上述两次改动针对的是不同分支:你可以在不同分支间不断地来回切换和工作,并在时机成熟时将它们合并起来。 而所有这些工作,你需要的命令只有branch、checkout 和 commit。

你可以简单地使用 git log 命令查看分叉历史。 运行 git log --oneline --decorate --graph
–all ,它会输出你的提交历史、各个分支的指向以及项目的分支分叉情况。
在这里插入图片描述

4、分支的新建与合并

让我们来看一个简单的分支新建与分支合并的例子,实际工作中你可能会用到类似的工作流。 你将经历如下步
骤:

  1. 开发某个网站。
  2. 为实现某个新的需求,创建一个分支。
  3. 在这个分支上开展工作。
    正在此时,你突然接到一个电话说有个很严重的问题需要紧急修补。 你将按照如下方式来处理:
  4. 切换到你的线上分支(production branch)。
  5. 为这个紧急任务新建一个分支,并在其中修复它。
  6. 在测试通过之后,切换回线上分支,然后合并这个修补分支,最后将改动推送到线上分支。
  7. 切换回你最初工作的分支上,继续工作。

1)、新建分支

首先,我们假设你正在你的项目上工作,并且已经有一些提交。

现在,你已经决定要解决你的公司使用的问题追踪系统中的 #53 问题。 想要新建一个分支并同时切换到那个分支上,你可以运行一个带有 -b 参数的 git checkout 命令:
在这里插入图片描述
你继续在 #53 问题上工作,并且做了一些提交。 在此过程中,iss53 分支在不断的向前推进,因为你已经检出 到该分支(也就是说,你的 HEAD 指针指向了 iss53 分支)
在这里插入图片描述
现在你接到那个电话,有个紧急问题等待你来解决。 有了 Git 的帮助,你不必把这个紧急问题和 iss53 的修改 混在一起,你也不需要花大力气来还原关于 53# 问题的修改,然后再添加关于这个紧急问题的修改,最后将这 个修改提交到线上分支。 你所要做的仅仅是切换回 master 分支。
在这里插入图片描述

这个时候,你的工作目录和你在开始 #53 问题之前一模一样,现在你可以专心修复紧急问题了。 请牢记:当你切换分支的时候,Git 会重置你的工作目录,使其看起来像回到了你在那个分支上最后一次提交的样子。 Git 会自动添加、删除、修改文件以确保此时你的工作目录和这个分支最后一次提交时的样子一模一样。

接下来,你要修复这个紧急问题。 让我们建立一个针对该紧急问题的分支(hotfix branch),在该分支上工作直到问题解决:
在这里插入图片描述
你可以运行你的测试,确保你的修改是正确的,然后将其合并回你的 master 分支来部署到线上。 你可以使用git merge 命令来达到上述目的:
在这里插入图片描述
在合并的时候,你应该注意到了"快进(fast-forward)"这个词。 由于当前 master 分支所指向的提交是你当前提交(有关 hotfix 的提交)的直接上游,所以 Git 只是简单的将指针向前移动。 换句话说,当你试图合并两个 分支时,如果顺着一个分支走下去能够到达另一个分支,那么 Git 在合并两者的时候,只会简单的将指针向前推进(指针右移),因为这种情况下的合并操作没有需要解决的分歧——这就叫做 “快进(fast-forward)”。
现在,最新的修改已经在 master 分支所指向的提交快照中,你可以着手发布该修复了。

关于这个紧急问题的解决方案发布之后,你准备回到被打断之前时的工作中。 然而,你应该先删除 hotfix 分支,因为你已经不再需要它了 —— master 分支已经指向了同一个位置。 你可以使用带 -d 选项的 git branch 命令来删除分支:
在这里插入图片描述
现在你可以切换回你正在工作的分支继续你的工作,也就是针对 #53 问题的那个分支(iss53 分支)。

2)、分支的合并

假设你已经修正了 #53 问题,并且打算将你的工作合并入 master 分支。 为此,你需要合并 iss53 分支到master 分支,这和之前你合并 hotfix 分支所做的工作差不多。 你只需要检出到你想合并入的分支,然后运行git merge 命令:
在这里插入图片描述

3)、遇到冲突时的分支合并

有时候合并操作不会如此顺利。 如果你在两个不同的分支中,对同一个文件的同一个部分进行了不同的修改,Git 就没法干净的合并它们。 如果你对 #53 问题的修改和有关 hotfix 的修改都涉及到同一个文件的同一处,在合并它们的时候就会产生合并冲突:

为了测试有冲突的情况,如图,除了master,我创建了两个分支sunjunfei和afei,准备对同一个文件进行操作,然后合并到master
在这里插入图片描述
首先对sunjunfei分支的afei.html进行修改,并提交
在这里插入图片描述
然后对afei分支的afei.html进行修改,并提交
在这里插入图片描述
接下来拉取master分支,将这两个分支合并到master
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
可以看到,提示我们afei.html有冲突,我们到这个文件看一看
在这里插入图片描述
我这里选择以afei分支的为主
在这里插入图片描述
点击完之后的结果
在这里插入图片描述
合并完冲突之后,再将这个最终结果推到master分支上
在这里插入图片描述
可以看到git上已经发生变化
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_41880073/article/details/119104953