Git总结

一、基本知识

1.初识Git
  1. git简介:git 是一个开源的分布式版本控制系统,用于敏捷高效地处理任何或小或大的项目;
  2. git与svn: git 是分布式的(每部电脑都有着自己的版本库),所以 git 支持离线工作,在本地可以进行很多操作,包括接下来将要重磅推出的分支功能。而 SVN 必须联网才能正常工作;
  3. 安装:
    *git  config --global user.name “name”
    *git  config – global user.email “email”
    1. 配置ssh key(配置之后不用每次push/pull都需要输入密码进行验证) *打开本地git bash,使用ssh-keygen -t rsa -C 'xxx@xxx.com'命令生成ssh公钥和私钥对 *windows 打开用户目录.ssh/下的id_rsa.pub文件,复制里面的内容 *打开gitlab,找到Profile Settings-->SSH Keys--->Add SSH Key,并把上一步中复制的内容粘贴到Key所对应的文本框,在Title对应的文本框中给这个sshkey设置一个名字,点击Add key按钮添加完成。
    2. 安装包下载地址:https://git-scm.com/downloads
      *解压安装包之后,选中安装路径,然后傻瓜式按默认选项安装即可,安装完成之后,在开始菜单里找到“Git”->“Git Bash”蹦出一个类似命令行窗口的东西,就说明Git安装成功或在命令窗口中输入git 回车,展示各种git常用命令代表安装完成。
    3. 配置邮箱及密码(自报名户)
2.Git基本原理

工作区和暂存区工作区:我们存放代码的地方叫做工作区。版本库:工作区有一个隐藏目录.git,这个不算工作区,而是Git的版本库。Git的版本库里存了很多东西,其中最重要的就是称为stage(或者叫index)的暂存区,还有Git为我们自动创建的第一个分支master,以及指向master的一个指针叫HEAD2733848a36e5353a9314d83955678b57.png第一步是用git add把文件添加进去,实际上就是把文件修改添加到暂存区;第二步是用git commit提交更改,实际上就是把暂存区的所有内容提交到当前分支。因为我们创建Git版本库时,Git自动为我们创建了唯一一个master分支,所以,现在,git commit就是往master分支上提交更改。你可以简单理解为,需要提交的文件修改通通放到暂存区,然后,一次性提交暂存区的所有修改。

举个例子来说:首先我们先对一格文件readme.md做个修改,比如加上如下一段内容:

Git is a distributed version control system.

然后再在工作区新增一个文件a.txt,我们使用git status查看一下状态:

$ git status
On branch master
Changes not staged for commit:
  (use "git add ..." to update what will be committed)
  (use "git checkout -- ..." to discard changes in working directory)
    modified:   readme.md
Untracked files:
  (use "git add ..." to include in what will be committed)
    a.txt
no changes added to commit (use "git add" and/or "git commit -a")

Git非常清楚地告诉我们,readme.md被修改了,而a.txt还从来没有被添加过,所以它的状态是Untracked

现在,使用两次命令git add,把readme.mda.txt都添加后,用git status再查看一下:

$ git status
On branch master
Changes to be committed:
  (use "git reset HEAD ..." to unstage)
    new file:   a.txt
    modified:   readme.md

现在暂存区就变成这样了198b4d70c8468fe4cbb91776cb691651.png

所以,git add命令实际上就是把要提交的所有修改放到暂存区(Stage),然后,执行git commit就可以一次性把暂存区的所有修改提交到分支。

$ git commit -m "add后的文件"
[master e43a48b] understand how stage works
 2 files changed, 2 insertions(+)
 create mode 100644 a.txt

一旦提交后,如果你又没有对工作区做任何修改,那么工作区就是“干净”的:

$ git status
On branch master
nothing to commit, working tree clean

现在版本库变成了这样,暂存区就没有任何内容了:17ef7ea5f5927419fdc0ea2ca050772e.png

在Git中,用HEAD表示当前版本,也就是最新的提交1094adb...(注意我的提交ID和你的肯定不一样),上一个版本就是HEAD^,上上一个版本就是HEAD^^,当然往上100个版本写100个^比较容易数不过来,所以写成HEAD~100

操作图:b2ca32288d6048ca13fe7356f13de5b3.png

3.分支

Git是鼓励我们使用分支的,一方面创建分支更加利于多人协作开发,功能开发;另一方面在迭代开发中,像master,Sprint这样的研发主线,我们需要保证它最大程度稳定性,需要从开发主线中分离出来

  1. 创建分支(git branch ) 创建分支可以这样理解,分支为当前工作目录的一份副本,如在下图标红处我拉出一个dev分支,实际上,此时dev分支与RD-SPYYYY001分支的版本库内容是完全一致的:3c540f9c2ac60b69160bf76b32fee199.png

  2. 切换分支(git checkout ) head默认是指向git为我们创建的分支master,当我们创建并切换分支时,head会重新指向至我们切换的分支,如我在本地liuchao新拉出一个test分支;当前分支为test,本地打开.git目录下的HEAD文件内容就可以看到,此时的head已经指向的test分支;打开.git目录下 refs\heads选中test文件,可以看到test分支指向的最新版本号,实际上这个版本号与liuchao分支当前的最新版本号一致。

  3. 其他分支常用命令 查看分支:git branch切换分支:git checkout   (前提当前分支工作区与暂存区无文件改动) 创建并切换分支:git branch –b 删除分支:git branch –D  (不能删除当前分支) 合并分支:git merge  (当前分支合并分支branchName,能看到合并先,形成一个新的commitID

4.冲突

冲突起因:

无论是从你从本地向远程push还是从远程pull代码时候都有可能会照成冲突,冲突原因都是在本地或者远程进行合并时,同一个文件被其他用户修改过,git无法得知保留哪次提交的内容。

解决冲突:

模拟冲突情景:本地库中两个不同分支,修改同一个文件同一代码块,两分支先后将修改合并到master分支上,master在合并第二个分支代码时,报错:合并冲突(如图一所示)。(这种情况类似我们平时pull远程代码时发生冲突) 打开冲突文件如图二所示,其中<<<<   === 是我们这次修改(本地)的内容,=== >>>是已经合并完成(远程)的修改;我们在与共同开发者协商完之后可手动修改保留的内容,或把文件通过编辑器vscode/idea等等,点击图二圈红内容快速选择需要保留的内容。通常我们在解决完冲突之后需要把重新提交合并,至此冲突解决。

ab94bf0c5d94b06626bfded1d720ae00.png
冲突
图一
3570f177162f7ffbbf01c55867843d6d.png
解决冲突
图二

二、常用命令

  1. 把暂存区中的文件覆盖工作目录的文件,在后续工作中遇到场景二会体现这个命令的用法
$ git checkout -- 
  1. 将文件从暂存区删除
$ git rm --cached
  1. 常用于版本回退,--后面可带的参数有多个如下图所示:
$ git  reset --(参数)  

17810e6d1d4ad6d1d895709ae11a68ee.pnggit reset --hard :强制撤销,重置工作区,暂存区,仓库的内容至指定版本git reset --mixed :默认参数,重置版本库至指定版本,保留工作区内容git reset --soft : 软撤销,重置仓库head的指向至指定版本,保留暂存区,工作区(当可重置后审查完可直接commit提交到版本) 注意:commitid除了用git log查询出来外,还可以用head替代,head代表上一个版本head^表示,head~100表示往上一百个版本

  1. 把工作区修改的内容压栈隐藏起来,适合场景有,比如你开发功能到一半时,这时你临时需要切换分支,但又不想提交代码这么快,这时就可以利用:
$ git stash

配合statsh常使用的命令还有:git stash pop : git栈中获取到最近一次stash进去的内容,恢复工作区的内容。。获取之后,会删除栈中对应的stashgit stash apply:出栈之后不会吧栈的内容删除git stash list:查看栈里边的列表信息git stash clear:清空栈里边的全部信息

  1. 作用为挑选某个分支的的某次提交内容到当前分支上
$ git  cherry-pick 

通常我们提交完代码至github上,负责人审核合并完成之后可直接在github客户端上点击页面上Cherry-pick按钮进行提内容挑选至指定分支上,但可能因为冲突或其他原因,我们需要手动cherry-pick

手动cherry-pick步骤如下:a.在源分支上,git log 查询到需要同步的commitid b.切换分支至目标分支上,执行git  cherry-pick即可

注意1:

若发生冲突,可手动解决冲突然后addcommit提交即可。

注意2:

若想一次同步多个commit的内容。需从最早的版本开始逐步往前同步。网上有种说法(整理ppt时才发现,未来得及验证):如源分支commit1  XXXX1commit2  XXXX2commit3  XXXX3 在目标分支上:git cherry-pick XXX1..XXX2    (中间的两个点表示把两个commit区间的commit都同步过去,但不包括第一个commit的内容)。

三、常遇场景

场景一:统一忽略不需要提交的文件

我们在开发有许多文件是不需要提交的,比如编译产生的.classpatchtarget目下的包 等等,我们可以使用git统一忽略这一类文件,在代码目录下有一个.gitignore隐藏文件,我们使用notepad++或其他编辑器打开,添加需要统一忽略的文件,如下图所示:cbb2b9cd6ce16678b3cee95977ba657b.png

场景二:撤销工作区修改的文件(未add至暂存区)

$ git checkout --  撤销指定文件
$ git checkout -- . 撤销当前工作目录的所有修改的文件

场景三:撤销暂存区的文件至工作区(未commit至本地库)

$ git reset head 
$ git reset head .

前面有提到reset命令的用法,改命令仅改变版本库,并不改变工作区,这意味着在无任何其他操作的情况下,工作区中的实际文件同该命令运行之前无任何变化。

场景四:撤销已commit至本地库的文件(未push值远程仓库)

$ git reset --hard HEAD^   (强制回退到未修改 未提交之前)
$ git reset HEAD^  # 此时代码保留,回到 git add 之前

场景五:撤销push至远程仓库的文件(未merge)

$ git log # 得到你需要回退一次提交的commit id 

方法一:

$ git reset --hard  (强制撤回)
$ git push origin HEAD --force # 强制提交一次,之前错误的提交就从远程仓库删除;若不是使用强删,可修改之后正常提交,前一次提交的记录也会被删除

方法二:

git revert   # 撤销指定的版本,撤销也会作为一次提交进行保存,之前提交的commit会被保留
1ad4d4a1a9f0739c4346d32f6afe11f9.png
公众号图片

最后认识一下,我是Zero,与期待您的关注O(∩_∩)O!,那下次见~

Logo

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。

更多推荐