git常用命令详解

说明

本文不是教程大全,也不过多探讨底层原理,重点在于讲解常用命令,及其正确的使用方法。因为总有新人甚至是工作两三年的人仍然会犯一些解决代码冲突时覆盖别人代码之类的错误。本文目标读者是对git有一定了解,已经安装使用过,可以进行简单的提交合并等操作,但偶尔会出错;知道一些git的概念,但又不是很清晰透彻。本文力求准确简洁,如有纰漏之处敬请指正。

重要概念

为了保证效果,先把重要的概念阐述一下,有助于后续的理解。

Git是什么

Git是一个开源的分布式版本控制系统,用以有效、高速的处理从很小到非常大的项目版本管理。(百度百科)

分布式: 指每个客户端都有完整的数据和历史提交记录。开发者不需要联网就可以本地提交。

集中式版本控制系统:
在这里插入图片描述

分布式版本控制系统:
在这里插入图片描述

三种状态

Git 有三种状态,你的文件可能处于其中之一:已提交(committed)已修改(modified)已暂存(staged)

  • 已修改表示修改了文件,但还没保存到数据库中。
  • 已暂存表示对一个已修改文件的当前版本做了标记,使之包含在下次提交的快照中。
  • 已提交表示数据已经安全地保存在本地数据库中。

这会让我们的 Git 项目拥有三个阶段:工作区、暂存区以及 Git 目录。
在这里插入图片描述

  • 工作区是从项目的某个版本独立提取出来的内容。 这些从 Git 仓库的压缩数据库中提取出来的文件,放在磁盘上供你使用或修改。工作区中的文件通俗点就是你所在的整个项目目录下,能看到并使用修改的文件(git目录的文件都在.git的隐藏目录下)。
  • 暂存区是.git目录下的一个文件,保存了下次将要提交的信息。按照 Git 的术语叫做“索引”,不过一般说法还是叫“暂存区”。(之所以设计暂存区,主要是为了分段提交。很多时候我们并不是把工作区中所有的修改都提交,试想我们修改了很多文件,最后提交的时候一个一个选择哪些是本次要提交的,是一件很繁琐的事情。有了暂存区,你修改了一点之后,可以先放到暂存区,最后一起提交。通常做完一个功能或解决完一个问题的时候才提交。)
  • Git 目录是 Git 用来保存项目的元数据和对象数据库的地方。这是Git中最重要的部分,当你从其他电脑上clone(克隆)一个仓库的时候,复制的就是这里的内容。

如果 Git 目录中保存着特定版本的文件,就属于已提交状态。 如果文件已修改并放入暂存区,就属于已暂存状态。 如果自上次检出后,作了修改但还没有放到暂存区域,就是已修改状态。

常用命令

获取Git仓库

本地创建

在指定的目录或新创建的目录下执行:

git init

从其他地方克隆一个Git仓库

(以下几条命令中project指项目名)
使用http协议:git clone http://ip:port/项目路径/project.git
使用ssh协议:git clone ssh://[user@]server/project.git
使用git协议: git clone git@域名:path.../project.git
以上三种格式都是通过网络克隆远程服务器的git仓库,如果git仓库在一个共享的文件系统上,也可以使用本地协议克隆该仓库,由于不经常使用,本文不再列举。

分支相关

获取git仓库之后就要进行本地开发了,通常一个项目有多个人员共同开发,为了减少冲突、方便管理,每个人都会创建自己的分支进行开发。通常每个任务创建一个分支,如果是新增功能性的开发,分支前缀可以是feature-,后面加任务编号或者缩写;如果是bug性的修复,分支前缀可以是bugfix-。

  • 查看本地分支:git branch
    (分支名字前面有*号的表示当前分支)
  • 查看远程分支:git branch -r
  • 查看所有分支:git branch -a
    (如果想查看最新的远程分支列表,可以先git fetch origin更新一下)
  • 基于当前分支新建分支:git branch branch-new
  • 基于指定分支新建分支:git branch branch-new base-name
    (基于远程分支新建base-name的名字需为origin/远程分支名)
  • 查看本地分支与远程分支的关联关系:git branch -vv
  • 切换分支:git checkout branch_A
    (branch_A为要切换到的分支名)
  • 创建新分支并切换到该分支:git checkout -b branch_A
    (该命令等于:1. git branch branch_A      2. git checkout branch_A)

远程相关

先明确几个概念:
origin,指远程库的别名或主机名。
origin/master, 指远程库master分支在本地的副本。

  • git remote 查看远程库别名,当clone仓库之后,默认远程库的别名是origin,当然也可以指定为其他的,这里不展开阐述。
  • git remote -v 查看远程库的详细地址。
  • git remote add <shortname> <url> 添加一个新的远程 Git 仓库,<shortname> 也称作“主机名”。

当克隆仓库或从远程检出分支到本地时,会自动将本地与远程对应的分支建立追踪关系,如master分支追踪origin/master分支,可以通过git branch -vv查看追踪关系:
在这里插入图片描述
上图有三个分支,a分支对应origin/a分支;master分支对应origin/master分支。
也可以手动添加追踪关系:git branch --set-upstream-to=origin/next b 该命令指定b分支追踪origin/next分支。

提交代码相关

  • git status
    查看文件状态。
    在这里插入图片描述
    如上图所示,该命令会显示三类文件内容:
    Untracked files:表示没有被追踪的文件;
    Changes not staged for commit:没有放入暂存区的修改内容;
    Changes to be commited: 已放入暂存区待提交的修改内容;
  • git add <filexxx> :把文件或修改添加到暂存区
  • git checkout -- <filexxx> :撤销工作区的修改,让这个文件回到最近的一次git commit或git add时的状态。
  • git reset HEAD <filexxx> :将修改从暂存区移除到工作区
  • git commit -m “描述信息” :将暂存区中的修改提交到git仓库中。如果不加 -m参数,那么是不能直接输入描述信息的,而是会调用一个编辑器来让你输入这个描述信息。
  • git commit -a -m “描述信息” : 加的-a参数可以将所有已跟踪文件中的执行修改或删除操作的文件都提交到本地仓库,即使它们没有经过git add添加到暂存区,未被跟踪的文件不会提交。尽量减少使用该参数。
  • git push 命用于从将本地的分支版本上传到远程并合并,git push <远程主机名> <本地分支名>:<远程分支名>,如果本地分支名与远程分支名相同,则可以省略冒号,git push <远程主机名> <本地分支名>。如:git push origin master 相当于 git push origin master:master;如果省略本地分支,表示删除该远程分支即推送一个空的分支到远程分支,如:git push origin :master 等同于git push origin --delete master

拉取代码

拉取远程代码并合并到本地分支用git pull;只拉取远程代码(更新),不合并用git fetch:

  • git pull <远程主机名> <远程分支名>:<本地分支名>
    从远程获取代码并合并到本地的版本
    假设当前分支为branch-L,默认远程主机名origin,则:
    git pull -------- 从默认远程主机origin 获取branch-L分支代码并合并到本地分支branch-L
    git pull origin dev -------- 从远程origin 获取dev分支的代码并合并到本地分支branch-L
    git pull origin dev:branch-L -------- 从远程origin 获取dev分支的代码并合并到本地分支branch-L

  • git fetch <远程主机名> <远程分支名>
    git fetch 更新所有远程库代码
    git fetch origin 更新origin对应远程库的代码

注:git pull 相当于(不完全一样) git fetch + git merge
假设本地当前分支为dev,则
git pull origin dev 相当于 git fetch origin dev + git merge origin/dev

合并代码相关

常用场景:在自己的分支branchA上开发完成,提交到远程,并在远程合并到dev分支时提示有冲突,这时需要本地更新下远程dev分支代码,并将其合并到branchA,遇到冲突解决掉,然后再把branchA分支push到远程。假设当前分支为branchA:

    更新远程dev分支代码:git fetch origin dev
    将远程dev分支代码合并到当前分支:git merge origin/dev
    (此时有冲突解决冲突,并提交)
    将当前分支的变更推送到远程:git push

git-merge - Join two or more development histories together

可见git merge命令是将两个或多个历史开发记录合并到一起。注意后面不管跟几个分支,最后都是合并到当前分支。假设当前分支为a,git merge b 是将分支b与a合并到a;git merge b c 是将分支b、c与a合并到a。

解决冲突

有时候待合并的分支和当前分支对同一个文件的相同部分作了不同的修改,这时候Git就没法干净的合并它们,提示有冲突,需要我们解决冲突。
假设当前分支为master主分支,此时想把iss53的修改合并到主分支上:

$ git merge iss53
Auto-merging index.html
CONFLICT (content): Merge conflict in index.html
Automatic merge failed; fix conflicts and then commit the result.

此时 Git 做了合并,但是没有自动地创建一个新的合并提交。 Git 会暂停下来,等待你去解决合并产生的冲突。 你可以在合并冲突后的任意时刻使用git status命令来查看那些因包含合并冲突而处于未合并(unmerged)状态的文件:

$ git status
On branch master
You have unmerged paths.
  (fix conflicts and run "git commit")
Unmerged paths:
  (use "git add <file>..." to mark resolution)
    both modified:      index.html
no changes added to commit (use "git add" and/or "git commit -a")

任何因包含合并冲突而有待解决的文件,都会以未合并状态标识出来。 Git 会在有冲突的文件中加入标准的冲突解决标记,这样你可以打开这些包含冲突的文件然后手动解决冲突。 出现冲突的文件会包含一些特殊区段,看起来像下面这个样子:

<<<<<<< HEAD:index.html
 <div id="footer">contact : email.support@github.com</div>
=======
 <div id="footer">
   please contact us at support@github.com
 </div>
>>>>>>> iss53:index.html

这表示HEAD所指示的版本(HEAD是指向当前分支的指针,可以理解为当前分支的别名)在这个区段的上半部分,而iss53分支所指示的版本在========的下半部分。 为了解决冲突,你必须选择使用由========分割的两部分中的一个,或者你也可以自行合并这些内容。 例如,你可以通过把这段内容换成下面的样子来解决冲突:

<div id="footer">
please contact us at email.support@github.com
</div>

上述的冲突解决方案仅保留了其中一个分支的修改,并且<<<<<<<,=======, 和>>>>>>>这些行被完全删除了。 在你解决了所有文件里的冲突之后,对每个文件使用git add命令来将其标记为冲突已解决。 一旦暂存这些原本有冲突的文件,Git 就会将它们标记为冲突已解决。

注意:这里需要注意解决冲突的时候是使用某一个分支的版本还是,各取一部分,需要根据实际情况。如果两个分支的修改都是你做的,你知道哪个版本更新,可以自己决定。如果不知道哪个更新,比如有几行其他人改过了,这时候需要根据代码记录找到对应的修改人,双方协商确认一下。否则容易造成代码丢失的现象。切忌在不是完全知情的情况下,私自覆盖他人的代码!!!!!!!

git add index.html
git commit -m "merge branch iss53 into master: #Conflicts: index.html "

将处理好的冲突文件修改添加到暂存区,然后提交可。

注意: 解决完冲突,将冲突文件的修改已经添加到暂存区,准备进行提交的时候,如果是在命令行中操作的,可以git status查看暂存区中要提交的文件列表,如果是图形化工具提交的,可以在对话框中查看提交的文件列表。
这时很多新手有个困惑,就是提交的文件列表里除了自己修改的文件,还有很多不是自己修改的,甚至有人手动取消这些文件,再提交。这样是不对的,会导致代码丢失。
暂存区的文件变更列表中会包含从最新状态到两个分支的共同祖先之间的所有变更过的文件列表。注意这里不仅包括自己的修改,也包括合并树的更改。所以此时不应该取消暂存区中的任何变更,直接提交即可。

在这里插入图片描述

补充:以上均为命令行操作,便于新手快速熟悉操作过程,并且命令行的功能是最完备的。当基本操作熟悉之后,就可以选择一个常用的图形化工具,使用起来更加方便。当然常用的IDE如eclipse、IDEA 等也都集成了git插件。

参考

1.https://www.git-scm.com/book/zh/v2/
2.https://www.jianshu.com/p/305723736c7c
3.https://www.cnblogs.com/drizzlewithwind/p/4878150.html

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值