Git命令行使用指南

题引:

既为了总结自己在Git使用上的实践经验,也为了给有同样Git使用需求的伙伴们提供借鉴。

本文Git使用方式为命令行。相信对Git有所了解的朋友,一定清楚,命令行在Git的使用中是最原子化的,也是最容易在使用过程中加深对Git原理理解的方式。任何Git的GUI操作工具,都是Git相关操作命令的子集。

什么是Git?Git和SVN的区别?使用Git有哪些好处?Git的冲突原理?怎么生成Git公钥私钥?这些问题不在本文讨论范围之内,有如上需求,请Google或者百度。

现在,我默认你已经拥有了Git的命令行终端工具(无论是Mac自带的终端,Windows下的git-bash终端,还是其它包含Linux使用方式的终端),并且已经配置好了Git的使用环境(账号及公钥私钥等问题)。

为了下文理解方便,这里简单普及Git中的三个概念:工作区、暂存区、版本库。

如何简单粗暴理解工作区、暂存区与版本库?

工作区:对克隆的项目中任何文件进行的任何改动,全部在工作区,无论你新增文件还是修改了文件

暂存区:凡是使用git add命令操作后的相关文件全部在暂存区(凡是能git commit的内容都在暂存区)

版本库:凡是经过git commit命令操作后的相关文件全部都在版本库,这里是本地版本库

远程版本库:凡是经过git push命令操作后的相关文件全部都在远程版本库

如何在命令行模式下轻易区分文件处于工作区、暂存区还是版本库?

绝大多数命令行终端工具(本文以windows下git-bash终端为例),对文件状态的显示有不同颜色:

工作区内容:无论修改还是新增的文件,呈现红色

暂存区内容:显示绿色

版本库内容:对不起,版本库内容默认没有显示,即使用git status看不到的文件都在版本库中

git status命令下文会有介绍

接下来介绍常用的Git命令及作用:

(1)Git特殊命令集(该特殊仅仅为了与下文中Git命令作用功能范围进行区分)
// 将某个文件夹初始化为Git版本库,无论该文件夹是否为空
git init

// 查看工作区、暂存区、版本库文件状态
git status

// 查看工作区中所有文件的修改内容
git diff

// 查看工作区中某个文件的修改内容,fileName可通过git status命令得到
git diff fileName

// 查看Git某个命令的帮助文档,直接在该命令后加--help参数即可,注意空格
git log --help    查看git log命令的帮助文档
git commit --help    查看git commit命令的帮助文档
git diff --help    查看git diff命令的帮助文档

// 暂存工作区中所有修改或新增的内容,使工作区清空(切换分支和pull代码时常用)
git stash

// 查看被暂存的内容
git stash show

// 将暂存的内容恢复至工作区
git stash pop

// 将a分支上的某次提交commitId应用到当前分支(挑选合并)
git cherry-pick commitId
(2)拉取远程代码相关
// 克隆远程版本库,https:xxx和ssh:xxx为远程Git仓库地址,https和ssh代表不同的通讯协议
git clone https:xxx    或者    git clone ssh:xxx

// 从远程版本库更新所有文件到本地版本库,并完成远程与本地对应分支的merge操作
git pull
(3)提交代码相关
添加工作区内容到暂存区:

    // 添加工作区所有修改或新增的文件到暂存区
    git add .

    // 添加工作区某个新增或修改的文件到暂存区,fileName可通过git status命令得到
    git add fileName

    // 添加工作区多个新增或修改的文件到暂存区,多个文件之间用空格隔开
    git add fileName1 fileName2 fileName3

提交暂存区内容到版本库:

    // 提交暂存区所有文件到版本库,"."代表所有文件,-m代表添加注释,这是方法一
    git commit . -m "提交注释"

    // 提交暂存区所有文件到版本库,"."代表所有文件,该命令会进入vi界面,可添加注释,这是方法二
    git commit .

    // 提交暂存区某个文件到版本库,fileName可通过git status命令得到,这是方法一
    git commit fileName -m "提交注释"

    // 提交暂存区某个文件到版本库,该命令会进入vi界面,可添加注释,这是方法二
    git commit fileName

    // 提交暂存区多个文件到版本库,多个文件之间用空格隔开,这是方法一
    git commit fileName1 fileName2 fileName3 -m "提交注释"

    // 提交暂存区多个文件到版本库,该命令会进入vi界面,可添加注释,这是方法二
    git commit fileName1 fileName2 fileName3

将本地版本库推送到远程版本库:

    // 将本地版本库推送到远程版本库,该命令会将本地分支推送到与本地对应的远程分支中
    git push
(4)查看提交日志相关
// 查看全部提交日志
git log

// 以一行的形式显示log的title
git log --oneline

// 查看提交修改了哪些内容
git log -p

// 查看某次提交修改了哪些内容
git show commitId

// 查看指定用户的提交, str可以是git中的用户名,也可以是正则表达式
git log --author=str

// 根据log中的一些关键词进行过滤,str可以是提交信息中的某些关键词,也可以是正则表达式
git log -grep=str

// 类似GUI工具显示方式查看日志及更改内容
gitk
(5)Git文件状态回退相关
工作区内容回退(该操作不可逆,无法找回,谨慎操作):

    // 工作区中修改的所有文件回退(放弃所有修改)
    git checkout .

    // 工作区中修改的某个文件回退,fileName可通过git status命令得到(放弃某个文件修改)
    git checkout fileName

    // 工作区中修改的多个文件回退,多个文件之间用空格隔开(放弃多个文件修改)
    git checkout fileName1 fileName2 fileName3

    // 工作区中新增的文件回退(删除新增的内容)
    直接使用linux中的删除文件相关命令:rm -f 或者 rm -rf

暂存区回退到工作区:

    // 所有文件:状态从暂存区回退到工作区
    git reset .

    // 某个文件:状态从暂存区回退到工作区,fileName可通过git status命令得到
    git reset fileName

    // 多个文件:状态从暂存区回退到工作区,多个文件之间用空格隔开
    git reset fileName1 fileName2 fileName3

本地版本库回退到工作区:

    // 放弃本次提交,lastCommitId为本次提交前的上一次提交的commitId
    git reset lastCommitId

远程版本库回退:

    // 放弃本次提交,commitId为本次提交的commitId,该方式为反转提交
    git revert commitId    --> 进入vi界面,可添加注释,也可直接保存退出
    --> git push
(6)解决冲突相关
// 出现了冲突,解决方式,该命令会打开比对工具进行冲突处理
git mergetool
(7)分支管理相关
// 合并a分支到当前分支
git merge a

// 变基a分支到当前分支(该命令可更改真实提交历史,不建议使用)
git rebase a

// 当前分支为a,想切换到分支b(切换分支时,工作区必须无修改或新增)
git checkout b

// 列出本地所有分支
git branch

// 列出远程所有分支
git branch -r

// 基于当前分支创建本地新分支
git branch newBranchName

// 基于当前分支创建本地新分支,并切换到新分支
git checkout -b newBranchName

// 删除本地存在的a分支,-D代表强制删除
git branch -D a

// 推送本地新分支到远程,建立远程对应新分支,一般情况localBranchName与remoteBranchName相同
git push origin localBranchName:remoteBranchName

// 建立本地分支与远程分支的关联映射关系,一般loalBranch与remoteBranch名称相同
git branch --set-upstream localBranch origin/remoteBranch

// 删除远程分支,把上一个命令中的localBranchName置为空即可,方法一
git push origin :remoteBranchName

// 删除远程分支,方法二
git push origin -d remoteBranchName

了解了常用的Git命令包,接下来介绍常用工作场景中如何使用这些命令:

工作场景一——克隆项目,拉取最新代码
1.克隆项目到本地仓库
git clone https:xxx    或者    git clone ssh:xxxx

2.克隆完成后,一般为服务器此时最新内容,如若又有人提交了新内容
git pull
工作场景二——提交代码
1.提交代码时,先更新
  git pull
  如果命令顺利结束,则更新结束并完成与本地对应分支的merge操作
  如果命令未顺利结束(git pull时提示错误),说明远程与本地可能存在冲突,可以:
    git stash // 将工作区的所有修改或新增暂存起来,保证工作区clean
    git pull // 此时一定可以将远程内容pull下来,因为工作区已经clean了
    git stash pop // 将暂存起来的内容应用到工作区,此时可能会发生冲突
    git mergetool // 进行冲突解决,如果没有冲突,则该命令会顺利结束,更新完成

2.提交代码(这里以某个文件为例,全部文件或多个文件的提交请参考上文的命令包)
  // 添加工作区待提交内容到暂存区
  git add fileName
  // 提交暂存区内容到本地版本库
  git commit fileName -m "提交注释"
  // 推送本地版本库到远程版本库,git push会默认推送到与本地关联的远程分支上
  git push
  如果git push命令顺利结束,则提交代码完成
  如果git push命令未顺利结束,出现错误提示,说明在你更新之后又有人推送了新内容到远程,此时可以:
    git pull // 将远程最新内容拉取下来
    git push // 再将自己的提交推送到远程,但此时git log上会包含一次merge提交记录,如果你想保证git log提交历史的整洁,可以:
      git log // 找到你此次提交的上一次提交lastCommitId
      git reset lastCommitId // 将本地版本库重置回你提交前的状态,工作空间依然会保留你所有的修改或新增
      重新执行提交代码流程(步骤2),此时会保证你的提交历史是干净的,不包含merge提交记录
工作场景三——挑选合并
假设你有两个分支,开发分支dev和测试分支test,你在dev分支上有几个提交想应用到test分支上,但又
不想进行分支的merge操作,你此时可以如此操作:

1.使用git log命令将dev分支上的这几次提交commitId按照时间先后顺序记录下来,假如为c1,c2,c3

2.使用git checkout test命令切换到test分支

3.在test分支使用git cherry-pick命令,按照时间先后顺序将c1,c2,c3合并进来
  git cherry-pick c1
  git cherry-pick c2
  git cherry-pick c3

4.然后将合并进来的提交推送到远程
  git push

5.注意:git cherry-pick 命令只针对正常的提交commitId有效,merge提交记录的commitId无效
工作场景四——创建新分支
假设你由于新需求,需要拉取新分支,并且想把本地新分支备份到远程,你可以:

1.更新当前分支的最新内容
  git pull

2.基于当前分支拉取新工作分支,并切换到新工作分支(你也可以先拉取新分支,再切换过去)
  git checkout -b newWorkBranch

3.推送新分支到远程上备份,remoteBranchName为你在远程的分支名
  git push origin localBranchName:remoteBranchName
工作场景五——分支合并
假如你因为新需求拉取了单独的开发分支dev1,现在新需求开发完毕,想将代码合并回主开发分支dev上,
此时你可以:

1.将dev1单独开发分支的代码拉取到最新
  git pull

2.将dev主开发分支代码拉取到最新,因为待会要进行提交操作
  git pull

3.将当前分支切换到主开发分支上,如果当前分支已在主开发分支上,忽略该操作
  git checkout dev

4.将dev1分支的内容合并到当前分支上
  git merge dev1

5.分支合并的过程是最容易产生冲突的地方,假设此时有冲突,需要解决冲突
  git mergetool
 
6.冲突解决完后,进行提交,git commit后会进入vi界面,可以添加合并注释信息也可保存退出
  git commit

7.将分支合并记录推送到远程
  git push
结束语

本文中,还有一些场景没有覆盖到,比如多团队协作分支的管控,变基git rebase命令的使用场景等。但绝大部分使用命令行可以完成的工作,在本文中都可以找到借鉴之处。如果大家有补充,欢迎留言进行交流,我会一一回复。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,919评论 6 502
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,567评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,316评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,294评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,318评论 6 390
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,245评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,120评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,964评论 0 275
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,376评论 1 313
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,592评论 2 333
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,764评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,460评论 5 344
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,070评论 3 327
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,697评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,846评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,819评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,665评论 2 354

推荐阅读更多精彩内容

  • 文章基于Mac版本的git操作. 关于 git. 之前一直使用SVN, 开发个人项目时会使用GitHub Desk...
    KenZhangCn阅读 460评论 0 0
  • 今天晚上不知怎么了,睡不着觉了。听着窗外的雨声滴滴答答,让我的思绪飞到了400多公里的那个地方—— 我的高中学校。...
    南方少年w阅读 202评论 0 1
  • 一杯酒,红灯挂高楼,赤纱帐子百折皱。试问夫君情意稠,嬿婉良时未肯休,举案齐眉百指柔,誓将年华作长久。 二杯酒,听君...
    络黎昀翕阅读 313评论 0 0