版本控制工具—— Git的使用

如果你要学习版本控制工具,那么Git一定是必不可少的,因为Git是当前最为先进的分布式版本控制系统,使用人数也是最多的,知名的代码托管平台GitHub就是最大的 Git 版本库托管商,它也是成千上万的开发者和项目能够合作进行的中心。本文将通俗地向你介绍Git的使用和其部分原理。

本文Git命令汇总

  1. 设置全局用户名和邮箱
    git config --global user.name "xxx"
    git config --global user.email xxx@xxx.com

  2. 查看配置信息
    git config --list

  3. 初始化本地仓库
    git init

  4. 克隆远程仓库
    git clone [URL]

  5. 追踪文件
    git add [文件名]
    git add .

  6. 提交文件到暂存区并添加备注信息
    git commit -m "备注信息"

  7. 删除文件
    git rm [文件名]

  8. 查看提交历史
    git log

  9. 覆盖上一次提交
    git commit --amend

  10. 取消暂存的文件
    git reset HEAD <file>...

  11. 恢复到上一个版本
    $ git reset --hard HEAD^

  12. 恢复到上n个版本
    $ git reset --hard HEAD~n

  13. 查看所有分支的操作记录(可查看版本号)
    git reflog

  14. 通过版本号恢复
    git reset --hard [版本号]

  15. 取消文件的修改
    git checkout -- < file>

  16. 生成SSH公钥
    $ ssh-keygen -t rsa -C "youremail@example.com

  17. 添加新的Git远程仓库
    git remote add <shortname> <url>

  18. 推送更改到远程仓库分支:
    git push [remote-name] [branch-name]

  19. 从远程仓库中抓取与拉取
    git fetch <url>
    git pull <url>

  20. 查看远程仓库信息
    git remote show [remote-name]

  21. 重命名远程仓库
    git remote rename [old name] [new name]

  22. 删除远程仓库
    git remote [remote-name]

  23. 克隆远程分支到本地
    git checkout –b [本地分支名] [remote-name]/[远程仓库分支名]

  24. 创建本地分支推送到远程仓库
    git push [remote-name] [远程仓库分支名]:[本地仓库分支名]

  25. 查看所有已跟踪的远程分支
    git branch -vv

  26. 创建分支
    git branch [分支名]

  27. 切换分支
    git checkout [分支名]

  28. 创建并切换分支
    git checkout -b [分支名]

  29. 合并目标分支到当前分支
    git merge [分支名]

  30. 删除某一分支
    git branch -d [分支名]

  31. 查看所有分支
    git branch

  32. 变基
    git rebase [分支名]

  33. 保存当前工作区
    git stash

  34. 恢复工作区并删除
    git pop

  35. 恢复工作区不删除
    git apply

  36. 查看工作区列表
    git stash list

  37. 新建一个附注标签
    git tag -a v1.0 -m"my first tag"

  38. 新建一个轻量标签
    git tag v1.1-w

  39. 查看标签的信息
    git show v1.0

  40. 查看已有的标签
    git tag

  41. 对历史提交记录打标签
    git tag -a v1.2 xxxxxxx
    xxxxxxx是提交记录的版本号,版本号可以用git reflog来查。

  42. 共享标签
    单个标签:git push [remote-name] [tag-name]
    多个标签:git push [remote-name] --tags

  43. 删除标签
    本地:git tag -d [tag-name]
    本地删除后同步到远程:git push [remote-name] :refs/tags/[rag-name]

  44. Git给命令起别名
    git config --global alias.xx xxxxxxx

相关知识

Git的安装

打开这个网址 http://git-scm.com/download/win 会自动下载。下载的这个项目包括git bash 和 git GUI 。如果你已经成功下载并安装,那么在桌面上单击鼠标右键,你就会发现这两个图标:
在这里插入图片描述

可能会用到的Linux命令

  1. 获取当前工作目录的绝对路径:pwd
  2. 查看当前目录下的所有文件:ls
  3. 切换目录:cd xxx
  4. 复制文件:cp xxx
  5. 删除文件:rm xxx
  6. 显示文件内容:cat xxx
  7. 清空屏幕:clear
  8. 新建文件并写入内容:echo “xxx” >> xxx

Git和SVN的区别

这个问题也可扩展为分布式和集中式版本控制系统的区别。

SVN属于集中式版本控制系统,项目会集中的保存到服务器上,开发人员要定期的从服务器上更新最新的项目版本到自己本地,工作之后再提交给服务器。脱离了服务器就没法工作。集中式版本控制系统必须在联网的情况下使用。

Git属于分布式版本控制系统,分布式相比于集中式的最大区别在于开发者可以提交到本地,每个开发者通过克隆(git clone),在本地机器上拷贝一个完整的Git仓库。push之后才会提交到远程仓库(为了开发者之间交换数据而约定好的一个仓库)。每个电脑都是一个独立的开发环境,所以不需要联网就可以提交。push时才需要联网。

Git的开发流程

常见的Git开发流程是这样的:

1、从服务器上克隆完整的Git仓库(包括代码和版本信息)到单机上。
2、在自己的机器上根据不同的开发目的,创建分支,修改代码。
3、在单机上自己创建的分支上提交代码。
4、在单机上合并分支。
5、把服务器上最新版的代码fetch下来,然后跟自己的主分支合并。
6、生成补丁(patch),把补丁发送给主开发者。
7、看主开发者的反馈,如果主开发者发现两个一般开发者之间有冲突(他们之间可以合作解决的冲突),就会要求他们先解决冲突,然后再由其中一个人提交。如果主开发者可以自己解决,或者没有冲突,就通过。
8、一般开发者之间解决冲突的方法,开发者之间可以使用pull 命令解决冲突,解决完冲突之后再向主开发者提交补丁

初次运行Git

现在我们在选择Git Bash Here,就会打开控制台,首次运行控制台很重要的一件事就是要设置用户名和邮箱。

$ git config --global user.name "xxx"
$ git config --global user.email  xxx@xxx.com

这一步操作很重要,因为你的每一次提交都会用到这些信息。

global意味着设置全局的用户名和邮箱。如果你想针对不同的仓库设置不同的信息,去掉global就可以,就像这样:

$ git config --user.name "xxx"
$ git config --user.email  xxx@xxx.com

还有一个你可能要用到的命令就是设置文本编辑器,git默认的文本编辑器是vim。

$ git config --global core.editor emacs

这个命令就是说git的编辑器设置为emacs。

如果更改配置完成后,想要查看当前的配置信息,输入这样的命令:

$ git config --list

获取Git仓库

有两种方式来获取一个Git仓库:

  1. 把当前目录下的所有文件导入到Git
  2. 克隆远程仓库到本地

如果你打算使用 Git 来对现有的项目进行管理:

  1. 在当前目录下,右键单击空白处----Git Bash Here
  2. 输入$ git init

这个命令会在你的项目目录下生成一个叫.git的隐藏文件,这个文件包含了所有你初始化的Git仓库需要的文件,它是Git仓库的主干。

如果你打算克隆远程仓库到本地,使用这个命令:

$ git clone [URL]

URL是你想要克隆的仓库的地址。

Git的基础使用

不论使用哪种方式获取仓库,总之,你现在有了一个真实项目的仓库。
和其他的版本控制工具一样,仓库中的所有文件不外乎两种状态:已跟踪和未跟踪。
已跟踪说明文件已经纳入Git的版本控制,未跟踪则说明文件没有纳入版本控制。
初次获取仓库时,默认将仓库中所有的文件都纳入版本控制,并且都处于未修改状态。
如果你修改了某些文件,那么这些被你修改的文件就会处于已修改状态。我们需要将其放进暂存区,之后再将暂存区的文件一并提交即可。

一个Git文件的生命周期如下:

在这里插入图片描述

场景一:新增加文件并提交

跟踪一个文件或者将一个已修改的文件放入缓存区的命令是:$ git add [文件名]

查看当前文件的状态用到的命令是$ git status

比如我们在仓库中新增一个文件叫 a.txt 我们查看状态时就会发现 Untracked files a .txt 也就是说,git提示你 a.txt 这个文件未跟踪:
在这里插入图片描述
我们按照它给的指示,使用add命令来跟踪a.txt ,然后再查看状态:

在这里插入图片描述
也就是说,a.txt已经被跟踪而且也加入到缓存区了,我们需要将其提交,提交暂存区的文件使用的命令是:$ git commit -m "备注信息"
在这里插入图片描述
或者你可以直接在控制台用vim新建一个文件,输入命令vim b.txt在这里插入图片描述
意思是新建一个叫b.txt的文件,回车之后会进入编辑界面,此时处于命令模式,按下 i 进入输入模式:
在这里插入图片描述
编辑完成之后,保存退出:Esc + : + wq + Enter,返回控制台。
之后的操作和我们上面的操作一样:

  1. 追踪这个文件,加入到暂存区$ git add b.txt
  2. 提交更改$ git commit -m"备注信息"

说明:使用$ gti add .会把所有更改的文件全部放入暂存区。

场景二:修改文件并提交

比如说现在a.txt文件被修改了,那么此时使用$ git status来查看:
在这里插入图片描述
会提示你a.txt被改动了,但是还没有被放置到暂存区,此时你需要使用$ git add a.txt,接着使用$ git commit -m "日志信息"来提交。
我们可以合并两个步骤,直接输入$ git commit -a -m "日志信息":
在这里插入图片描述
值得注意的是,如果a.txt是新增的文件,那么不能这样操作。

一个小问题:有一个waring注意到了吗?由于在不同的操作系统中换行符的不同,导致了这个警告。解决方法很简单,Git 可以在你提交时自动地把回车(CR)和换行(LF)转换成换行(LF),而在检出代码时把换行(LF)转换成回车(CR)和换行(LF)。 你可以用$ git config --global core.autocrlf false进行设置。

场景三:删除文件并提交

使用git rm [文件名]来删除文件,比如说我们现在要删除b.txt,就要使用$ git rm b.txt,这意味着将b.txt将不再纳入Git的版本控制,并且从文件目录中删除ta。如果你只是想将其移除版本控制,而不删除其原文件,那么就要使用$ git rm -cached b.txt

下面我们来演示一下最基本的删除:

在这里插入图片描述此时返回目录,我们会发现b.txt已经被删除。

  • 特殊情况:如果你想要删除已经在暂存区还未提交的文件,必须要用强制删除选项 -f(译注:即 force 的首字母)即$ git rm b.txt -f。 这是一种安全特性,用于防止误删还没有添加到快照的数据,这样的数据不能被 Git 恢复。

场景四:查看提交历史

这个算是版本控制系统最常用到的功能之一了,在git中查看提交历史只需要输入命令$ git log即可:
在这里插入图片描述
不添加其他参数,默认不用任何参数的话,git log 会按提交时间列出所有的更新,最近的更新排在最上面。详细信息包括作者,作者邮箱,时间,备注信息等。

你还可以添加其他参数来查找你想要找的提交历史:

  1. -p 显示每次提交的内容差异,你也可以加上 -2 来仅显示最近两次提交

在这里插入图片描述

  1. –stat 查看每次提交的简略统计信息

–stat 选项会在每次提交的下面列出所有被修改过的文件、有多少文件被修改了以及被修改过的文件的哪些行被移除或是添加了。在最后还会有一个总结。

  1. 限制 git log 输出的选项
选项说明
-(n)仅显示最近的 n 条提交
–since, --after仅显示指定时间之后的提交。
–until, --before仅显示指定时间之前的提交。
–author仅显示指定作者相关的提交。
–committer仅显示指定提交者相关的提交。
–grep仅显示含指定关键字的提交
-S仅显示添加或移除了某个关键字的提交
  1. git log 的常用选项
选项说明
-p按补丁格式显示每个更新之间的差异。
–stat显示每次更新的文件修改统计信息。
–shortstat只显示 --stat 中最后的行数修改添加移除统计。
–name-only仅在提交信息后显示已修改的文件清单。
–name-status显示新增、修改、删除的文件清单。
–abbrev-commit仅显示 SHA-1 的前几个字符,而非所有的 40 个字符。
–relative-date使用较短的相对时间显示(比如,“2 weeks ago”)。
–graph显示 ASCII 图形表示的分支合并历史。
–pretty使用其他格式显示历史提交信息。可用的选项包括 oneline,short,full,fuller 和 format(后跟指定格式)。

场景五:撤销操作

任何时候你都可能会有想要撤销的操作。

覆盖上一次提交

有时候我们提交完了才发现漏掉了几个文件没有添加,或者提交信息写错了。 此时,可以运行带有 --amend 选项的提交命令尝试重新提交。我们来演示一下:
在这里插入图片描述
可以看到,在首次提交后(备注信息是add a new file),我改动了c.txt,然后运行命令git commit --amend,然后更改了备注信息。那么这次提交会覆盖上一次提交,通过查看提交历史信息我们可以看到,只有一次提交信息。

取消暂存区的文件

使用 git reset HEAD <file>... 来取消暂存的文件:

在这里插入图片描述
我们可以来查看一下当前的文件状态:
在这里插入图片描述
说明取消暂存成功。

恢复版本

我们已经知道使用$ git log命令可以查看提交历史记录,如果你想回退到上一个版本,就需要使用$ git reset --hard HEAD^,回退到上上一个版本的命令是$ git reset --hard HEAD^^,以此类推…那么如果你想会退到前100个版本,只需要输入git reset --hard HEAD~100即可,这是简便写法。
另外一种恢复版本的方法是先通过$git reflog查看版本号,再使用git reset --hard [版本号]来恢复版本。

取消文件的修改

上一个案例中我修改了c.txt,如果我想取消修改,该如何操作?
$ git checkout -- < file>
状态信息已经给我们提示了:use “git checkout – < file>…” to discard changes in working directory。
在这里插入图片描述
可以看到,修改被取消了。

  • 非常重要

你要知道的是,取消修改是一个非常危险的命令,除非你非常明确你不想保存这些更改,否则,不要使用这个命令,因为它极有可能造成文件的永久性丢失。Git中提供了非常强大的数据恢复功能,甚至已经被删除的分支中的数据也可以恢复,但是,这一切都是建立在commit的基础上,如果你的文件没有提交,擅自使用这个命令就是非常危险的。

场景六:操作远程仓库

GitHub能够收到如此大的追捧很大一部分原因是因为它开源的特性,任何人都可以复制项目到本地,任何人都可以参与项目的开发。学习本地仓库库与远程仓库的同步非常有必要,这会使得你有效的管理你的远程仓库,并且在必要的时候参与到别的项目。如果GitHub使用起来不太方便的话,你可以使用码云代替。

  • 步骤
  1. 生成SSH-Key

github和本地是通过SSH加密传输的,生成SSH-Key的命令是$ ssh-keygen -t rsa -C "youremail@example.com",邮箱就是你在github上注册时使用的邮箱。回车之后会要求你确认路径和密码,不用管,一路回车就可以。完成之后它会给出提示:

Your identification has been saved in ~/.ssh/id_rsa.
Your public key has been saved in ~/.ssh/id_rsa.pub.

d_rsa是私钥,不能泄露出去,id_rsa.pub是公钥,可以放心地告诉任何人。也就是说,公钥被保存在 ~/.ssh/id_rsa.pub这个文件下,我们使用cat ~/.ssh/id_rsa.pub来打开这个文件,就会看到生成的公钥,复制它。或者你也可以在电脑上根据路径自己找到这个文件,进入复制。
有了公钥之后,我们在浏览器上打开我们的github,点击进入settings:
在这里插入图片描述
在左侧选择SSHSSH and GPG keys在这里插入图片描述
在右侧点击New SSH Key
在这里插入图片描述
把你刚才复制的公钥粘贴进去,再给它随便起个名字就可以了,之后会要求你输入密码,按照指示操作就可以了。添加成功后会出现:
在这里插入图片描述
之后你需要确保你的github上有一个可用的仓库,如果没有的话,新建一个:在这里插入图片描述
输入仓库的名字,你也可以再加上一些其他配置信息,之后点击创建
在这里插入图片描述
创建成功后会给我们一个提示:
在这里插入图片描述
远程仓库建好了,公钥也上传了,下面,我们就在本地clone这个远程仓库,并且保持它们之间的同步。

  1. 添加新的Git远程仓库
    git remote add <shortname> <url>
    添加一个新的远程 Git 仓库,同时指定一个你可以轻松引用的简写来代整个URL。

上面我已经建好了一个远程仓库,我们把它的地址拷贝下来,比如我的这个仓库的SSH地址是git@github.com:Y00-H00/bloTest.git。
我们在本地仓库下运行Git Branch,就输入git remote add mygit git@github.com:Y00-H00/bloTest.git,添加远程仓库。

  1. 提交本地更改到远程仓库
    推送到远程仓库:git push [remote-name] [branch-name]

比如我现在要新建一个a.txt并推送到远程仓库:

$ echo "# git test"  >> a.txt 			#创建a.txt并写入内容
$ git add a.txt							#添加到暂存区
$ git commit -m"新增a.txt"				#提交变更到本地
$ git push -u mygit master				#推送至远程仓库master分支

注意,mygit是我上面添加远程仓库时给起的别名。首次提交我们加上-u,不但会把内容提交到master分支上,并且还会把本地的master和远程仓库的master关联起来,以后就可以直接使用git push [remote-name] [branch-name]来推送本地的更新到远程仓库分支了。

完成了推送,我们返回github,就会看到这个新增的文件:
在这里插入图片描述

  • 克隆远程仓库到本地
    上面的场景是我们已经有了一个本地仓库,然后使用git remote add <shortname> <url>新增远程仓库到本地,如果你没有创建本地仓库,你可以在任何一个非Git文件夹下直接克隆远程仓库到本地:
    $ git clone [url]
    clone下来的仓库默认名叫origin。
    默认情况下,git clone 命令会自动设置本地 master 分支跟踪克隆的远程仓库的 master 分支。
    克隆远程仓库到本地之后,你就可以向上面的操作一样,推动本地变更到远程分支了。

  • 从远程仓库中抓取与拉取
    git fetch <url>
    这个命令会去访问远程仓库,从中下载新的分支和数据到本地供你使用。fetch并不会自动的合并远程分支到本地(需要你自己选择是否合并)。此处name可以是你添加仓库时给起的别名。
    git pull <url>
    这个命令与fetch基本类似,不同的是,pullfetch会自动的合并远程分支到本地。一般来说,fetch更加安全一些。

  • 查看远程仓库
    如果想要查看某一个远程仓库的更多信息,可以使用git remote show [remote-name]命令。

这个命令非常好用,它可以告诉你非常有意思的东西。

  • 重命名远程仓库
    如果想要重命名引用的名字,可以运行 git remote rename [old name] [new name] 去修改一个远程仓库的简写名。

  • 删除远程仓库
    git remote [remote-name]

  • 克隆远程分支到本地
    git checkout –b [本地分支名] [remote-name]/[远程仓库分支名]

  • 创建本地分支推送到远程仓库
    git push [remote-name] [远程仓库分支名]:[本地仓库分支名]

  • 查看所有已跟踪的远程分支
    git branch -vv

分支的使用

  • Git的分支特性

单独把分支列出来足以说明它的重要性,几乎所有的版本控制系统都支持分支。使用分支意味着你暂时脱离主线开发,在不影响主线开发的前提下进行你的工作。在有的版本控制工具中,使用分支意味着你需要下载一个完整的项目副本,项目小点还好说,但是一旦项目变得十分庞大,就显得略微低效了。不同于这些版本控制系统, Git 处理分支的方式非常轻量,它鼓励频繁的创建分支或者合并,这正是Git的强大之处。

  • 分支原理简述

Git在你每一次的commit操作时会保存一个提交对象,这个提交对象包含了作者的信息和一个树对象索引,树对象又包含了目录结构和所有的文件快照对象的索引,每一个提交对象对应着一个项目版本,所以在任何时候,都可以重现某个版本的数据。Git的分支其本质是指向提交对象的可变指针,我们是用git init 初始化时会默认帮我们创建一个master分支(我们更习惯称之为主干),它和其他所有人为创建的分支并没有区别,你每提交一次,分支的指针就会向前前进,指向一个新的提交对象(代表新的项目版本)。可想而知,每个分支都会指向一个各自的提交对象,分支之间的切换就意味着版本之间的切换,那么合并分支时,Git就会根据两个分支各自代表的版本和它们的共同祖先来进行合并,从而产生一个新的版本。并且,Git中有一个特殊的指针HEAD,它用来指向当前所在的本地分支,分支之间的切换就是HEAD指针的移动。

  • 关于Git分支更详细原理讲解:传送门

  • 分支操作常用命令

  1. 创建分支-git branch [分支名]
  2. 切换分支-git checkout [分支名]
  3. 创建并切换分支-git checkout -b [分支名]
  4. 合并目标分支到当前分支git merge [分支名]
  5. 删除某一分支-git branch -d [分支名]
  6. 查看所有分支-git branch
  • 分支开发工作流

一般来说,分支大概有长期分支,短期分支,特性分支,bug分支等等,master扮演的角色是长期分支,只有稳定的版本才会往master分支上合并,develop是基于master的并行分支,也是长期分支,永远不会和master合并,团队中的所有开发人员在develop下创建属于自己的特性分支feature来开发特性功能,它是短期分支,并在工作完成后选择性地合并到master和develop中。develop这条分支负责主线开发,会存储所有的项目版本(稳定+不稳定),而master中只存储上线的版本(稳定)。如果遇到了bug,就要从master上单开一条hotfix或者issxxx的短期分支用来修复bug,完成后合并到master和develop上。所有的短期分支都会在工作完成后,合并到长期分支后删除。

  • 如果你想了解更多关于Git分布式开发流:传送门

变基

  • git rebase [分支名]

我们已经知道merge命令会将两个分支进行合并,生成一个全新的版本。其实,还有另外一种方法来整合分支,就是变基rebase(不得不说这个名字起得太好了),执行变基命令就会将在另外一个分支上的变更提取出来并应用到当前分支上。它的原理很简单,我们都知道,两个分支一定会有一个共同祖先,Git会参照这个祖先来查阅分支进行了那些变更,然后提取相应的修改保存为临时文件,然后按照修改顺序将这些修改应用在当前分支上。尽管两个结果相同,但是变基会使得历史记录看上去像是串行的一样,没有分叉,可以保持提交历史的整洁。在这种情况下,你首先在自己的分支里进行开发,当开发完成时你需要先将你的代码变基到 origin/master 上,然后再向主项目提交修改。 这样的话,该项目的维护者就不再需要进行整合工作,只需要快进合并便可。

使用变基的准则是:不要对在你的仓库外有副本的分支执行变基

为什么呢?试想一下,变基操作的实质是丢弃一些现有的提交,然后新建与之内容一样但是实际上不同的提交, 如果你已经将提交推送至某个仓库,而其他人也已经从该仓库拉取提交并进行了后续工作,此时,如果你用 git rebase 命令重新整理了提交并再次推送,你的同伴因此将不得不再次将他们手头的工作与你的提交进行整合,如果接下来你还要拉取并整合他们修改过的提交……

总的原则是,只对尚未推送或分享给别人的本地修改执行变基操作清理历史,从不对已推送至别处的提交执行变基操作

场景一:紧急修复BUG

我们来模拟一下真实的开发场景,比如说你正在develop下的feature分支下工作,突然接到领导电话,说master分支上的稳定版本发现了一个BUG,要求你立即修复。那么此时你就要基于master分支再新建一个分支hotfix,hotfix的初始版本会和master稳定版本一致(一般develop下的版本都要比master下的版本新),也就是说你的工作目录切换到了之前的版本。

要注意保存你正在基于develop的feature下的工作进度,最好保持一个干净的状态,否则可能会与hotfix中发生冲突,一些方法可以绕过这个问题(即,保存进度(git stash) ,返回是使用命令git stash pop或者git stash apply)继续工作。

在hotfix下完成紧急修复之后,把它合并到master上,然后再合并到develop分支上,最后切换到feature分支下继续工作。

  • hotfix示意图:
    在这里插入图片描述
    C代表版本,不管是哪条分支,版本号是共享的,一般来说,develop上的版本是最完整的。
    C2代表master上上线的最新的稳定版本,C3是develop上处于开发阶段你的不稳定版本,C4是经过紧急修复BUG后的版本。

  • 案例演示:

  1. 本地新建仓库
  2. 模拟稳定版本,新建一个a.txt,保存,提交
  3. 基于master创建分支develop
  4. 基于develop创建分支feature-1
  5. 切换到feature-1,模拟主线开发,新建一个b.txt,修改
  6. 紧急修复,保存当前工作进度,切换到master分支,新建hotfix分支
  7. 切换到hotfix分支,新建c.txt,保存,提交,合并到develop和master
  8. 修复完毕,删除hotfix分支,切换到feature-1继续工作。
伟酱@LAPTOP-RSN1U635 MINGW64 ~/Desktop/hotFixDemo
$ git init 	#初始化仓库
Initialized empty Git repository in C:/Users/76583/Desktop/hotFixDemo/.git/

伟酱@LAPTOP-RSN1U635 MINGW64 ~/Desktop/hotFixDemo (master)
$ echo "i am a" >> a.txt	#新建一个a.txt,并输入内容

伟酱@LAPTOP-RSN1U635 MINGW64 ~/Desktop/hotFixDemo (master)
$ git add .		#添加进暂存区

伟酱@LAPTOP-RSN1U635 MINGW64 ~/Desktop/hotFixDemo (master)
$ git commit -m "模拟稳定版本"	#提交
[master (root-commit) 4196a97] 模拟稳定版本
 1 file changed, 1 insertion(+)
 create mode 100644 a.txt

伟酱@LAPTOP-RSN1U635 MINGW64 ~/Desktop/hotFixDemo (master)
$ git checkout -b develop	#创建develop分支并切换
Switched to a new branch 'develop'

伟酱@LAPTOP-RSN1U635 MINGW64 ~/Desktop/hotFixDemo (develop)
$ git checkout -b feature-1		#创建feature-1分支并切换
Switched to a new branch 'feature-1'

伟酱@LAPTOP-RSN1U635 MINGW64 ~/Desktop/hotFixDemo (feature-1)
$ echo "i am b" >> b.txt	#新建b.txt并添加内容

伟酱@LAPTOP-RSN1U635 MINGW64 ~/Desktop/hotFixDemo (feature-1)
$ git add .

伟酱@LAPTOP-RSN1U635 MINGW64 ~/Desktop/hotFixDemo (feature-1)
$ git status	#b.txt已经加入到暂存区
On branch feature-1
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

        new file:   b.txt


伟酱@LAPTOP-RSN1U635 MINGW64 ~/Desktop/hotFixDemo (feature-1)
$ git stash		#保存当前的工作进度去修复bug
Saved working directory and index state WIP on feature-1: 4196a97 模拟稳定版本

伟酱@LAPTOP-RSN1U635 MINGW64 ~/Desktop/hotFixDemo (feature-1)
$ git checkout master		#切换到master分支
Switched to branch 'master'

伟酱@LAPTOP-RSN1U635 MINGW64 ~/Desktop/hotFixDemo (master)
$ git checkout -b hotfix	#master下新建hotfix分支并切换
Switched to a new branch 'hotfix'

伟酱@LAPTOP-RSN1U635 MINGW64 ~/Desktop/hotFixDemo (hotfix)
$ echo "i am c" >> c.txt	#修复bug,增加c.txt

伟酱@LAPTOP-RSN1U635 MINGW64 ~/Desktop/hotFixDemo (hotfix)
$ git add .

伟酱@LAPTOP-RSN1U635 MINGW64 ~/Desktop/hotFixDemo (hotfix)
$ git commit -m "紧急修复"
[hotfix 0cab0fa] 紧急修复
 1 file changed, 1 insertion(+)
 create mode 100644 c.txt

伟酱@LAPTOP-RSN1U635 MINGW64 ~/Desktop/hotFixDemo (hotfix)
$ git checkout master	
Switched to branch 'master'

伟酱@LAPTOP-RSN1U635 MINGW64 ~/Desktop/hotFixDemo (master)
$ git merge hotfix		#合并hotfix分支到master分支
Updating 4196a97..0cab0fa
Fast-forward
 c.txt | 1 +
 1 file changed, 1 insertion(+)
 create mode 100644 c.txt

伟酱@LAPTOP-RSN1U635 MINGW64 ~/Desktop/hotFixDemo (master)
$ git checkout develop		#切换到develop分支
Switched to branch 'develop'

伟酱@LAPTOP-RSN1U635 MINGW64 ~/Desktop/hotFixDemo (develop)
$ git merge hotfix		#合并hotfic分支到develop分支
Updating 4196a97..0cab0fa
Fast-forward
 c.txt | 1 +
 1 file changed, 1 insertion(+)
 create mode 100644 c.txt

伟酱@LAPTOP-RSN1U635 MINGW64 ~/Desktop/hotFixDemo (develop)
$ git branch -d hotfix		#删除hotfix分支
Deleted branch hotfix (was 0cab0fa).

伟酱@LAPTOP-RSN1U635 MINGW64 ~/Desktop/hotFixDemo (develop)
$ git checkout feature-1	#切换到feature-1分支
Switched to branch 'feature-1'

伟酱@LAPTOP-RSN1U635 MINGW64 ~/Desktop/hotFixDemo (feature-1)
$ git stash list	#查看工作区列表
stash@{0}: WIP on feature-1: 4196a97 模拟稳定版本

伟酱@LAPTOP-RSN1U635 MINGW64 ~/Desktop/hotFixDemo (feature-1)
$ git stash pop		#切换到上一个工作区并且在工作区列表中删除
On branch feature-1
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

        new file:   b.txt

Dropped refs/stash@{0} (ee0c37f07e1b3790adc4b61c8e3782493f57d3cd)

场景二:解决冲突

解决冲突是使用Git必须要掌握的技能,产生冲突的原因是在没有更新版本的情况下两个人修改了同一份文件,接着进行了合并。解决冲突的方法很简单,由两个人商量对冲突文件进行修改,再次提交。

我们在本地模拟一下:

  • 场景模拟
  1. 新建仓库
  2. 新建a.txt文件,提交
  3. 新建develop分支并切换
  4. 修改a.txt,提交
  5. 切换到master分支
  6. 修改a.txt,提交
  7. 合并develop到master,产生冲突
  8. 修改冲突文件a.txt
  9. 再次提交,解决冲突

伟酱@LAPTOP-RSN1U635 MINGW64 ~/Desktop/confiltTest
$ git init
Initialized empty Git repository in C:/Users/76583/Desktop/confiltTest/.git/

伟酱@LAPTOP-RSN1U635 MINGW64 ~/Desktop/confiltTest (master)
$ echo "111111" >> a.txt

伟酱@LAPTOP-RSN1U635 MINGW64 ~/Desktop/confiltTest (master)
$ git add .

伟酱@LAPTOP-RSN1U635 MINGW64 ~/Desktop/confiltTest (master)
$ git commit -m "新增a.txt"
[master (root-commit) a715dfc] 新增a.txt
 1 file changed, 1 insertion(+)
 create mode 100644 a.txt

伟酱@LAPTOP-RSN1U635 MINGW64 ~/Desktop/confiltTest (master)
$ git checkout -b develop
Switched to a new branch 'develop'

伟酱@LAPTOP-RSN1U635 MINGW64 ~/Desktop/confiltTest (develop)
$ vim a.txt

伟酱@LAPTOP-RSN1U635 MINGW64 ~/Desktop/confiltTest (develop)
$ git add .

伟酱@LAPTOP-RSN1U635 MINGW64 ~/Desktop/confiltTest (develop)
$ git commit -m "develop update a"
[develop 252a0b7] develop update a
 1 file changed, 1 insertion(+)

伟酱@LAPTOP-RSN1U635 MINGW64 ~/Desktop/confiltTest (develop)
$ git checkout master
Switched to branch 'master'

伟酱@LAPTOP-RSN1U635 MINGW64 ~/Desktop/confiltTest (master)
$ vim a.txt

伟酱@LAPTOP-RSN1U635 MINGW64 ~/Desktop/confiltTest (master)
$ git add .

伟酱@LAPTOP-RSN1U635 MINGW64 ~/Desktop/confiltTest (master)
$ git commit -m "master update a"
[master 5cc0e73] master update a
 1 file changed, 1 insertion(+)

伟酱@LAPTOP-RSN1U635 MINGW64 ~/Desktop/confiltTest (master)
$ git merge develope
merge: develope - not something we can merge

伟酱@LAPTOP-RSN1U635 MINGW64 ~/Desktop/confiltTest (master)
$ git merge develop	
Auto-merging a.txt
CONFLICT (content): Merge conflict in a.txt
Automatic merge failed; fix conflicts and then commit the result.

伟酱@LAPTOP-RSN1U635 MINGW64 ~/Desktop/confiltTest (master|MERGING)
$ cat a.txt
111111
<<<<<<< HEAD
333333
=======
222222
>>>>>>> develop

伟酱@LAPTOP-RSN1U635 MINGW64 ~/Desktop/confiltTest (master|MERGING)
$ vim a.txt

伟酱@LAPTOP-RSN1U635 MINGW64 ~/Desktop/confiltTest (master|MERGING)
$ cat a.txt
111111
333333
222222

伟酱@LAPTOP-RSN1U635 MINGW64 ~/Desktop/confiltTest (master|MERGING)
$ git add .

伟酱@LAPTOP-RSN1U635 MINGW64 ~/Desktop/confiltTest (master|MERGING)
$ git commit -m "update confilt file"
[master 1063332] update confilt file

伟酱@LAPTOP-RSN1U635 MINGW64 ~/Desktop/confiltTest (master)
$ git status
On branch master
nothing to commit, working tree clean

标签的使用

打标签是所有版本控制系统都会有的功能,Git同样支持给某次提交打标签以示重要。

Git中的标签分为两种,一种是轻量标签,一种是附注标签。
轻量标签就像一个不会改变的分支,它是一次特定提交的引用,本质上是将提交校验和存储到一个文件中 - 没有保存任何其他信息。
附注标签是存储在Git库中的一个完整对象,会包含一些信息等,是可以被校验的。

  • 标签命令
  1. 新建一个附注标签
    git tag -a v1.0 -m"my first tag"
  2. 新建一个轻量标签
    git tag v1.1-w
  3. 查看标签的信息
    git show v1.0
  4. 查看已有的标签
    git tag
  5. 对历史提交记录打标签:git tag -a v1.2 xxxxxxx
    xxxxxxx是提交记录的版本号,版本号可以用git reflog来查。
  6. 共享标签
    单个标签:git push [remote-name] [tag-name]
    多个标签:git push [remote-name] --tags
    这样,就会把你本地的标签同步到远程仓库,别人push后也会看到这些标签。
  7. 删除标签
    本地:git tag -d [tag-name]
    本地删除后同步到远程:git push [remote-name] :refs/tags/[rag-name]

Git别名

得承认的是,Git虽然很强大,但是复杂的命令对于新手来说并不友好(不推荐使用界面化工具),你可以通过起别名来订制属于你的Git命令:

$ git config --global alias.co checkout
$ git config --global alias.br branch
$ git config --global alias.ci commit
$ git config --global alias.st status

就像这样,那么,你就可以使用co代替checkout,使用br代替branch……

提交准则

有一个好的创建提交的准则并且坚持使用会让与 Git 工作和与其他人协作更容易。 Git 项目提供了一个文档给出了一些建议,可以在 Git 源代码中的 Documentation/SubmittingPatches 文件中阅读它。

  1. 空白错误的解决

空白错误是指行尾的空格、Tab 制表符,和行首空格后跟 Tab 制表符的行为。提交之前使用git diff --check将会找到可能的空白错误并将它们为你列出来。

  1. 尝试让每一个提交成为一个逻辑上的独立变更集

一次性提交多个巨大的变更是不友好的,这会使得其他开发者在查看历史时很艰难,你可以使用暂存区域将你的工作最少拆分为每个问题一个提交,并且为每一个提交附带一个有用的信息。 如果其中一些改动修改了同一个文件,尝试使用 git add --patch来部分暂存文件。

  1. 优质的提交信息

有一个创建优质提交信息的习惯会使 Git 的使用与协作容易的多。 一般情况下,信息应当以少于 50 个字符(25个汉字)的单行开始且简要地描述变更,接着是一个空白行,再接着是一个更详细的解释。

  • 示例:
修改的摘要(50 个字符或更少)

如果必要的话,加入更详细的解释文字。在
大概 72 个字符的时候换行。在某些情形下,
第一行被当作一封电子邮件的标题,剩下的
文本作为正文。分隔摘要与正文的空行是
必须的(除非你完全省略正文);如果你将
两者混在一起,那么类似变基等工具无法
正常工作。

空行接着更进一步的段落。

  - 句号也是可以的。

  - 项目符号可以使用典型的连字符或星号
    前面一个空格,之间用空行隔开,
    但是可以依据不同的惯例有所不同。

GitHub的使用

Fork

Fork功能是GitHub一个非常有趣的功能,即使你没有权限对这个仓库推送内容,使用fork可以在你的空间中创建一个完全属于你的项目副本。如果你想将在该项目副本的改动推送到源版本库,也可以创建合并请求(Pull Request)。创建了合并请求后,就会开启一个可供审查代码的板块,项目的拥有者和贡献者可以在此讨论相关修改,直到项目拥有者对其感到满意,并且认为这些修改可以被合并到版本库。

GitHub流程

GitHub设计了一个以合作请求为中心的特殊工作流程。

  1. 从master分支中创建一个新的分支
  2. 提交修改改进项目
  3. 推送这个分支至GitHub
  4. 创建一个合作请求
  5. 讨论,根据实际情况继续修改
  6. 项目的拥有者合并或者关闭你的合并请求

如果你想了解GitHub更详细使用:传送门

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
IDEA Git是IntelliJ IDEA集成的版本控制系统,可以帮助开发人员更好地管理和协作开发项目。使用IDEA Git,您可以执行各种操作,如提交修改、拉取和推送代码、解决冲突等。以下是关于IDEA Git使用方法: 1. 初始化Git仓库:在IDEA中打开您的项目后,可以通过右键单击项目根目录并选择"Git" > "Initialize Git Repository"来初始化Git仓库。这将在项目文件夹中创建一个名为".git"的隐藏文件夹,表示Git仓库已经初始化成功。 2. 提交修改:当您对代码进行修改后,可以通过右键单击文件或文件夹并选择"Git" > "Commit File"或者"Commit Directory"来提交修改。在提交窗口中,您可以选择要提交的文件、编写提交消息并提交修改。 3. 拉取和推送代码:在多人协作项目中,您可能需要从远程仓库拉取代码或将代码推送到远程仓库。使用IDEA Git,您可以通过右键单击项目根目录并选择"Git" > "Pull"或"Git" > "Push"来执行这些操作。在弹出的对话框中,您可以选择要拉取或推送的分支以及其他相关选项。 4. 解决冲突:当多个人同时修改同一文件并尝试推送到远程仓库时,可能会发生冲突。在IDEA中,您可以使用代码比对工具来解决冲突。首先,复制您的代码以备份,然后选择接受别人的代码,最后使用代码比对工具将备份的代码与IDEA中的代码进行对比,解决冲突。 5. 克隆项目:如果您想从远程仓库克隆一个项目到本地,可以通过使用Git地址克隆。在IDEA中,您可以通过选择"Check out from Version Control" > "Git",然后在弹出的对话框中填入Git地址和本地目录来克隆项目。 以上是关于IDEA Git的一些基本使用方法。希望对您有所帮助。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [详解IDEA Git Reset 选项说明](https://download.csdn.net/download/weixin_38666785/12924530)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* *3* [IDEA中如何使用Git——图文超详细,包会](https://blog.csdn.net/QingXu1234/article/details/127006467)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值