超全的Git实用技巧

507 阅读8分钟

星空.jpg

本文收纳了大量常用 git 命令,几乎能够满足git使用过程中的大部分场景的使用, 非常适合作为你的日常工作速查手册

希望深入了解 git 的同学,请前往 Pro Git 中文版 下载 《Pro Git》手册进行学习

Cherish作为一名菜鸟程序员在刚刚接触git时,虽然仔细阅读了《Pro Git》的第一、二章,基本清楚了git的使用流程,然而在实际运用中,却因为记不住各种常用的git 命令而常常畏手畏脚,经常因为使用了错误的git命令而把工作搞得焦头烂额,因为不记得各种 git 命令,常常要在使用时临时翻看手册,在经历过一番煎熬后,我下定决心要对常用的 git 技巧进行一个简练概括的总结,以下是我结合参考资料和平时的日常使用总结出来的n个git 实用技巧。随着在工作中更过使用场景的丰富,还会不断添加新的技巧,不断丰富和完善。

一、基本操作

如何新建仓库?

1.1. 将尚未进行版本控制的本地目录转换为 Git 仓库

  • 进入该项目得目录中;
$ cd /c/user/my_project
  • 执行 git init
$ git init
  • 使用 git add 追踪已存在得项目文件;
$ git add *.c
  • 使用 git commit 进行初始提交;
$ git commit -m 'initial project version' // 提交时添加comments

现在,你已经得到了一个存在被追踪文件与初始提交的 Git 仓库。

1.2 从其它服务器 克隆 一个已存在的 Git 仓库

  • 克隆命令: git clone <url>
$ git clone https://github.com/libgit2/libgit2
  • 如果你想在克隆远程仓库的时候,自定义本地仓库的名字,你可以通过额外的参数指定新的目录名:
$ git clone https://github.com/libgit2/libgit2 myName

Git 支持多种数据传输协议。 上面的例子使用的是 https:// 协议,不过你也可以使用 git:// 协议或者使用SSH 传输协议,比如 user@server:path/to/repo.git 。

如何查看当前项目中文件的状态?

  • 可以用 git status 命令查看哪些文件处于什么状态(状态信息比较详细)
$ git status
On branch master
Your branch is up-to-date with 'origin/master'.
nothing to commit, working directory clean
  • 使用 git status -s 命令或 git status --short 命令 (状态信息比较简洁)
$ git status -s
  • 最具体得查看方式: git diff ,可具体到具体更改文本内容
$ git diff

如何跟踪一个新添加的文件?

  • git add 文件名
$ git add xxx文件

如何暂存一个已修改得文件?

  • 还是 git add 文件名 命令,这是一个多功能命令
$ git add xxx文件

add 添加已存在文件的所有变化(新创建的文件不会被添加)

  • git add -a
$ git add -a

add 添加被修改(modified)和被删除(deleted)文件,不包括新文件(new)

  • git add -u
$ git add -u

撤销 git add 添加的文件

  • git reset HEAD 文件名
// 先使用 git status 查看已添加的文件的状态,文件名等
git status

//  modified:   src/composables/Common/common.ts

// git reset HEAD 文件名
git reset HEAD src/composables/Common/common.ts

添加新文件(new)和被修改(modified)文件,不包括被删除(deleted)文件

  • git add .
$ git bash .

如何忽略某些无需纳入 git 管理得文件?

  • 创建一个 .gitignore
$ cat .gitignore
  • 在该文件中添加需要忽略得文件;
*.[oa] // 忽略所有以 .o 或 .a 结尾的文件
*~ // 忽略所有名字以波浪符(~)结尾的文件

文件 .gitignore 的格式规范如下: • 所有空行或者以 # 开头的行都会被 Git 忽略。 • 可以使用标准的 glob 模式匹配,它会递归地应用在整个工作区中。 • 匹配模式可以以(/)开头防止递归。 • 匹配模式可以以(/)结尾指定目录。 • 要忽略指定模式以外的文件或目录,可以在模式前加上叹号(!)取反。

  • 查看已暂存的将要添加到下次提交里的内容
$ git diff --staged

如何提交更新

  • 使用 git status 查看文件状态,看看是否有未暂存得文件;
$ git status
  • 使用 git commit 提交更新
$ git commit
  • 可以在 commit 命令后添加 -m 选项,将提交信息与命令放在同一行,可不必打开编辑器编辑提交信息
$ git commit -m "Story 182: Fix benchmarks for speed"
[master 463dc4f] Story 182: Fix benchmarks for speed
2 files changed, 2 insertions(+)
create mode 100644 README

提交后它会告诉你,当前是在哪个分支(master)提交的,本次提交的完整 SHA-1 校验和是什么(463dc4f),以及在本次提交中,有多少文件修订过,多少行添加和删改过 请记住,提交时记录的是放在暂存区域的快照。 任何还未暂存文件的仍然保持已修改状态,可以在下次提交时纳入版本管理。

如何跳过暂存步骤,直接提交所有已跟踪的修改过得文件

  • 给 git commit 加上 -a 选项,Git 就会自动把所有已经跟踪过的文件暂存起来一并提交,从而跳过 git add 步骤
$ git commit -a -m 'added new benchmarks'

如何将纳入git版本管理的文件排除版本管理

要从 Git 中移除某个文件,就必须要从已跟踪文件清单中移除,然后提交

  • git rm 命令完成此项工作,并连带从工作目录中删除指定的文件
$ git rm PROJECTS.md
rm 'PROJECTS.md'
$ git status
On branch master
Your branch is up-to-date with 'origin/master'.
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
deleted: PROJECTS.md

如何查看提交历史?

  • git log 命令
$ git log
commit ca82a6dff817ec66f44342007202690a93763949
Author: Scott Chacon <schacon@gee-mail.com>
Date: Mon Mar 17 21:52:11 2008 -0700
changed the version number

如何撤销对文件的修改?

  • 如果你并不想保留对某个文件的修改怎么办? 你该如何方便地撤消修改——将它还原成上次提 交时的样子? git checkout -- 文件名
$ git checkout -- 文件名

请务必记得 git checkout -- 是一个危险的命令。 你对那个文件在本地的任何修改都会消失——Git 会用最近提交的版本覆盖掉它。

二、分支管理

如何创建新的分支?

  • 使用 git branch 命令,在当前分支的基础上创建一个新的分支
$ git branch 分支名

如何切换分支?

  • 使用 git checkout 分支名 命令,切换到一个已存在的分支
$ git checkout 分支名
  • 通常我们会在创建一个新分支后立即切换过去,这可以用 git checkout -b <newbranchname> 一条命令搞定;

如何查看分支分叉历史?

  • 使用 git log 命令

新建分支并切换到该分支上

$ git checkout -b 分支A

该语句是下面两句的简写:

$ git branch 分支A
$ git checkout 分支A

合并目标分支(将目标分支合并到当前分支上)

  • git merge 目标分支 将目标分支合并到当前分支
$ git checkout master // 切到 master
$ git merge hotfix // 将hotfix 合并到 master

如何删除一个不需要的分支?

  • 使用 git branch -d 分支名
$ git branch -d hotfix
Deleted branch hotfix (3a0874c)

在合并分支时遇到冲突怎么办?

  • 现象:
$ 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 会在有冲突的文件中加入标准的冲突解决标记,这样你可以打开这些包含冲突的文件然后手动解决冲突。

<<<<<<< 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

为了解决冲突,你必须选择使用由 ======= 分割的两部分中的一个,或者你也可以自行合并这些内 容。上述的冲突解决方案仅保留了其中一个分支的修改,并且 <<<<<<< , ======= , 和 >>>>>>> 这些行被完全删除了。在你解决了所有文件里的冲突之后,对每个文件使用 git add 命令来将其标记为冲突已解决。 一旦暂存这些原本有冲突的文件,Git 就会将它们标记为冲突已解决。 如果你想使用图形化工具来解决冲突,你可以运行 git mergetool,该命令会为你启动一个合适的可视化合并工具,并带领你一步一步解决这些冲突.

git branch 命令如何使用?

  • git branch 命令不只是可以创建与删除分支。 如果不加任何参数运行它,会得到当前所有分支的一个列表;
$ git branch
iss53
* master  // * 代表当前指针所在位置
testing
  • git branch -v 查看每一个分支的最后一次提交;
$ git branch -v
iss53 93b412c fix javascript issue
* master 7a98805 Merge branch 'iss53'
testing 782fd34 add scott to the author list in the readmes
  • git branch --merged 查看哪些分支已经合并到当前分支;
$ git branch --merged
iss53
* master

如何重命名分支

1. 本地分支重命名

  • 处于想要重命名的分支
git branch -m new_branch_name
  • 不处于想要重命名的分支
git branch -m old_branch_name new_branch_name

2. 远程分支重命名

假设远程分支和本地分支名一致

  • 重命名本地分支
git branch -m new_branch_name
  • 删除远程分支
git push --delete origin old_branch_name
  • 上传新命名的本地分支
git push origin new_branch_name
  • 关联修改后的本地分支与远程分支
git branch --set-upstream-to origin/new_branch_name

三、远程仓库

如何查看远程仓库?

  • 如果想查看你已经配置的远程仓库服务器,可以运行 git remote 命令。如果你已经克隆了自己的仓库,那么至少应该能看到 origin ——这是 Git 给你克隆的仓库服务器的默认名字;
$ git remote
origin
  • 如果你的远程仓库不止一个,该命令会将它们全部列出;

如何添加远程仓库?

  • 运行 git remote add <shortname> <url> 添加一个新的远程 Git 仓库,同时指定一个方便使用的简写;
$ git remote
origin
$ git remote add pb https://github.com/paulboone/ticgit
$ git remote -v
origin https://github.com/schacon/ticgit (fetch)
origin https://github.com/schacon/ticgit (push)
pb https://github.com/paulboone/ticgit (fetch)
pb https://github.com/paulboone/ticgit (push)

如何从远程仓库中抓取(fetch)和拉取(pull)?

  • 从远程仓库中获得数据,可以执行 git fetch <remote> ;
$ git fetch <remote>

这个命令会访问远程仓库,从中拉取所有你还没有的数据。 执行完成后,你将会拥有那个远程仓库中所有分支的引用,可以随时合并或查看。 必须注意 git fetch 命令只会将数据下载到你的本地仓库——它并不会自动合并或修改你当前的工作。 当准备好时你必须手动将其合并入你的工作

  • git pull 命令来自动抓取后合并该远程分支到当前分支
$ git pull

如何推送到远程仓库?

  • 使用 git push <remote> <branch>
$ git push origin xxx分支

如何查看某个远程仓库的信息?

  • 使用 git remote show <remote> 命令;
$ git remote show origin
* remote origin
Fetch URL: https://github.com/schacon/ticgit
Push URL: https://github.com/schacon/ticgit
HEAD branch: master
Remote branches:
master tracked
dev-branch tracked
Local branch configured for 'git pull':
master merges with remote master
Local ref configured for 'git push':
master pushes to master (up to date)

它同样会列出远程仓库的 URL 与跟踪分支的信息。 这些信息非常有用,它告诉你正处于 master 分支,并且如果运行 git pull, 就会抓取所有的远程引用,然后将远程 master 分支合并到本地 master 分支。 它也会列出拉取到的所有远程引用

如何移除远程分支?

  • 使用 git remote removegit remote rm

四、远程分支

如何操作远程分支?

  • 使用 git ls-remote <remote> 来显示地获取远程引用的完整列表

  • 使用 git remote show <remote> 获取远程分支的更多信息

29. 如何配置编辑注释时使用得编辑器?

  • 启动的编辑器是通过 Shell 的环境变量 EDITOR 指定的,一般为 vim 或 emacs。 当然也可以按照 起步 介绍的方式, 使用 git config --global core.editor 命令设置你喜欢的编辑器。

什么是跟踪远程分支?

  • 从远程分支 checkout 出来的本地分支,称为 跟踪分支 (tracking branch)。跟踪分支是一种和某个远程分支有直接联系的本地分支。
  • 在跟踪分支里输入 git push,Git 会自行推断应该向哪个服务器的哪个分支推送数据。同样,在这些分支里运行 git pull 会获取所有远程索引,并把它们的数据都合并到本地分支中来。

如何自定义设置跟踪分支?

  • 使用 git checkout -b [branch] [remotename]/[branch]
$ git checkout -b [branch]  [remotename]/[branch]
// 从远程分支上的 branch 分支上牵出一个 名为branch 的本地分支

如果想要将本地分支与远程分支设置为不同名字,可以使用如下示例命令:

$ git checkout -b sf origin/serverfix
Branch sf set up to track remote branch serverfix from origin.
Switched to a new branch 'sf'

以上,本地分支 sf 会自动从 origin/serverfix 拉取。

这是一个十分常用的操作,所以 Git 提供了 --track 快捷方式。

  • 自定义牵出远程分支的快捷方式: git checkout --track origin/serverfix
$ git checkout --track origin/serverfix
Branch serverfix set up to track remote branch serverfix from origin.
Switched to a new branch 'serverfix'

如何设置本地分支跟踪某个远程分支?

  • 使用 git branch -u origin/serverfix 或者 git branch --set-upstream-to origin/serverfix 可设置本地分支跟踪某个远程分支,或者修改正在跟踪的远程分支
$ git branch -u origin/serverfix
Branch serverfix set up to track remote branch serverfix from origin.

如何查看所有设置的跟踪分支?

  • 使用 git branch -vv 命令,这会将所有的本地分支列出来
$ git branch -vv
  iss53     7e424c3 [origin/iss53: ahead 2] forgot the brackets
  master    1ae2a45 [origin/master] deploying index fix
* serverfix f8674d9 [teamone/server-fix-good: ahead 3, behind 1] this should do it
  testing   5ea463a trying something new

这里可以看到 iss53 分支正在跟踪 origin/iss53 并且 ahead'' 是 2,意味着本地有两个提交还没有推送到服务器上。 也能看到 master 分支正在跟踪 origin/master 分支并且是最新的。 接下来可以看到 serverfix 分支正在跟踪 teamone 服务器上的 server-fix-good 分支并且领先 2 落后 1,意味着服务器上有一次提交还没有合并入同时本地有三次提交还没有推送。 最后看到 testing 分支并没有跟踪任何远程分支。

如何统计最新的领先与落后数字?

  • 使用命令 git fetch --all; git branch -vv

如何删除远程分支?

  • 使用带有 --delete 选项的 git push 命令来删除一个远程分支;
$ git push origin --delete serverfix
To https://github.com/schacon/simplegit
 - [deleted]         serverfix

如何强制覆盖本地代码(与git远程仓库保持一致)

  • 第一步:拉取所有更新,不同步;
git fetch --all
  • 第二步:本地代码同步线上最新版本(会覆盖本地所有与远程仓库上同名的文件)
git reset --hard 远程分支名

如:

git reset --hard origin/master
  • 第三步:再拉取一次远程分支得代码(其实没啥用,心理作用,再拉一次靠谱点)
git pull

持续更新中。。。

五、Git Stash

在项目开发中,如果我们正在当前分支开发某个需求,突然遇到要切换分支去修改bug时,此时我们不想将当前的修改提交到远程分支,那么我们可以使用 git stash命令先存放起来。git stash 常用命令如下:

git stash save "xxx"

存放时添加备注便于查找;当然只执行git stash 也可以,系统会自动为我们添加备注,但不便于查找。

git stash save "clear logs"

git stash list

查看存放列表

git stash list

在这里插入图片描述

git stash show

显示改动信息,默认展示第一个存储,如果要显示其它存储,后面加stash@{index},比如第二个 git stash show stash@{1}

git stash show stash@{1}

在这里插入图片描述

git stash show -p

显示第一个存储的改动,如果想显示其它存储,git stash show stash@{index} -p ,比如第二个:git stash show stash@{1} -p

git stash show  stash@{1} -p

git stash pop

恢复之前存储的工作目录,将缓存堆栈中的对应stash删除,并将对应修改应用到当前的工作目录下,默认为第一个stash,即stash@{0},如果要应用并删除其他stash,命令:git stash pop stash@{$num} ,比如应用并删除第二个:git stash pop stash@{1}

git stash pop
或
git stash pop stash@{1}

git stash apply

应用某个存储,但其不会从存储列表中删除,默认使用第一个存储,即stash@{0},如果要使用其他个,git stash apply stash@{index} , 比如第二个:git stash apply stash@{1}

git stash apply
或
git stash apply stash@{1}

git stash drop stash@{index}

丢弃stash@{index}存储,从列表中删除某个存储

git stash clear

清除存储列表中的所有stash

git stash clear