前言

最近用 GitHub 搭建了个人博客,顺便再回顾一下之前了解过但是没熟练掌握的 Git ,本篇主要是记录关于 Git 的一些命令和技巧,学习途径——廖雪峰Git教程,详细教程可以阅读廖雪峰Git教程

git 新更改: git checkout 可替换命令 git switchgit restore ,这里的笔记以新更改为主。


基本配置

–global:设置全局变量,局部变量则无需 --global 参数。

设置用户信息

1
2
git config --global user.name "用户名"
git config --global user.email "用户邮箱"

查看配置信息

1
2
git config --global user.name
git config --global user.email

Git 基础操作

初始化 Git 仓库

工作区(workspace):

  • 未跟踪(untracked):新创建文件。
  • 未暂存(unstaged):修改已有文件。
1
git init

把文件添加到仓库

工作区(workspace) –> 暂存区(index)

已暂存(staged):提交到仓库之前的缓存区。

1
git add <file>

把文件提交到仓库

暂存区(index) –> 本地仓库(repository)

说明:如果把文件提交到仓库后,工作区(workspace)无操作,则暂存区(index)是干净的。

1
git commit -m "本次提交的说明"

查看文件状态

1
git status

查看文件不同

  1. git diff:是查看 working tree 与 index 的差别的。
  2. git diff --cached:是查看 index 与 repository 的差别的。
  3. git diff HEAD:是查看 working tree 和 repository 的差别的。其中:HEAD 代表的是最近的一次 commit 的信息。
1
git diff <file>

显示提交日志

options

  • --all:显示所有分支。
  • --pretty=oneline:将提交信息显示为一行。
  • --abbrev-commit:使得输出的commit更简短。
  • --graph:以图的形式显示。
1
git log [options]

查看历史命令

1
git reflog

撤销修改

无参:撤销工作区(workspace)的修改。

--staged:撤销上传到暂存区(index)。

1
git restore [--staged] <file>

回退版本

回退上个版本

回退多个版本可以把 ^ 换成 ~<回退版本数>

1
git reset --hard HEAD^

回退到指定版本

1
git reset --hard <commit id>

删除文件

注意:从来没有被添加到版本库就被删除的文件,是无法恢复的!

文件修改后,与版本库不同时,再删除,此时options:

  • --cached:仅删除暂存区里的文件。此时 commit ,会出现工作区存在修改后的删除文件,而版本库此文件被删除。

  • -f :强制删除[工作区+暂存区]。此时 commit ,会出现工作区和版本库此文件都删除。

理解:

  1. rm <file> 可以在任何文件夹都可以用,包括不是git仓库的地方,是用来删除文件。如果用在git仓库里,则可以视为删除工作区的文件

  2. git rm <file> 只能在git仓库里使用,是用来删除(工作区+暂存区)的文件用的,如果此文件被修改过则要加入参数 -f 来删除(工作区+暂存区)的文件。

  3. git rm --cached <file> 如果想仅删除暂存区里的文件可以用此命令,它不会删除工作区中的文件。

建议:

  1. rm 或者鼠标点击的方式删除文件。

  2. 用命令 git rm <file> 确认删除文件。

  3. 用命令 git restore <file> 返回被删除的文件(无论文件修改与否,返回的都是未修改前的文件)。

1
git rm [options] <file>

关联远程库 GitHub

在新建空白 GitHub 仓库时,也会生成可以关联 git 的命令。

repo-name:克隆仓库名。

user-name:克隆仓库的用户名。

server-name:基本上是 github.com。

1
git remote add origin git@server-name:path/repo-name.git;

推送到 GitHub

把本地库的内容推送到远程,用 git push 命令,实际上是把当前分支 master 推送到远程。

由于远程库是空的,我们第一次推送 master 分支时,加上了 -u 参数,Git 不但会把本地的 master 分支内容推送的远程新的 master 分支,还会把本地的 master 分支和远程的 master 分支关联起来,在以后的推送或者拉取时就可以简化命令。

origin:远程库的名称。

本地仓库推送到远程仓库

1
git push <远程仓库名> <本地分支名>:<远程分支名>

初次推送

1
git push -u origin master

非初次推送

1
git push origin master

远程库操作

查看远程库

1
git remote -v

删除远程库

注意:此处的“删除”其实是解除了本地和远程的绑定关系,并不是物理上删除了远程库。远程库本身并没有任何改动。要真正删除远程库,需要登录到 GitHub ,在后台页面找到删除按钮再删除。

1
git remote rm <远程库名称>

SSH 克隆远程库

repo-name:克隆仓库名。

user-name:克隆仓库的用户名。

dir:要克隆到本地的文件目录,默认是”./“。

1
git clone git@github.com:user-name/repo-name.git [dir]

HTTPS 克隆远程库

https-link:克隆仓库的 https 链接。

dir:要克隆到本地的文件目录,默认是”./“。

1
git clone https-link [dir]

分支管理

新建分支

1
git branch <分支名>

切换分支

-c: 新建分支并切换到该分支。

1
git switch [-c] <分支名>

查看当前分支

当前分支会带”*“号。

1
git branch

合并分支

git merge 命令用于合并指定分支到当前分支。

Fast-forward:合并是“快进模式”,也就是直接把当前分支指向要合并分支的当前提交,所以合并速度非常快。但这种模式下,删除分支后,会丢掉分支信息。

--no-ff:表示禁用 Fast forward,从分支历史上就可以看出分支信息。

-m:合并要创建一个新的commit。

分支策略:

在实际开发中,我们应该按照几个基本原则进行分支管理:

首先, master 分支应该是非常稳定的,也就是仅用来发布新版本,平时不能在上面干活;

那在哪干活呢?干活都在 dev 分支上,也就是说, dev 分支是不稳定的,到某个时候,比如1.0版本发布时,再把 dev 分支合并到 master 上,在 master 分支发布1.0版本;

你和你的小伙伴们每个人都在 dev 分支上干活,每个人都有自己的分支,时不时地往 dev 分支上合并就可以了。

1
git merge [options] <要合并到当前分支的分支名>

删除分支

-d:删除分支。

-D:强制删除,用于没有合并的分支。

1
git branch -d/-D <分支名> 

BUG 分支

  • 封存当前工作现场(封存已跟踪文件)。
1
git stash
  • 查看封存的工作现场。
1
git stash list
  • 恢复封存的工作现场

    • git stash apply 恢复,但是恢复后,stash内容并不删除,你需要用 git stash drop 来删除。
    1
    git stash apply <恢复编号>
    1
    git stash drop <恢复编号>
    • git stash pop ,恢复的同时把stash内容也删了。
    1
    git stash pop
  • 复制已有 bug 分支(如果是未提交的工作现场,要先封存或提交,才能复制已有 bug 分支)。

1
git cherry-pick <bug 版本号>

多人协作

因此,多人协作的工作模式通常是这样:

  1. 首先,可以试图用 git push origin <branch-name> 推送自己的修改;
  2. 如果推送失败,则因为远程分支比你的本地更新,需要先用 git pull 试图合并;
  3. 如果合并有冲突,则解决冲突,并在本地提交;
  4. 没有冲突或者解决掉冲突后要 addcommit 后,再用 git push origin <branch-name> 推送就能成功!

如果 git pull 提示 no tracking information ,则说明本地分支和远程分支的链接关系没有创建,用命令 git branch --set-upstream-to <branch-name> origin/<branch-name>

这就是多人协作的工作模式,一旦熟悉了,就非常简单。

整理分支线

特点:把分叉的提交历史“整理”成一条直线,看上去更直观。缺点是本地的分叉提交已经被修改过了。

使用:本地分支过时与远程分支。

1
git rebase

标签管理

创建标签

  • 指定分支打标签,首先要切换到指定分支。
  • commit id:指定版本号创建标签。
  • options:-a 指定标签名, -m 指定说明文字。
1
git tag [options] <标签名> [commit id]

查看标签

  • 查看所有标签
1
git tag
  • 查看标签信息
1
git show <标签名>

删除标签

  • 删除标签
1
git tag -d <标签名>
  • 删除远程标签
1
git push origin :refs/tags/<标签名>

推送标签

  • 推送指定标签
1
git push origin <标签名>
  • 推送全部标签
1
git push origin --tags

忽略特色文件

在Git工作区的根目录下创建一个特殊的 .gitignore 文件,然后把要忽略的文件名填进去,Git就会自动忽略这些文件。

不需要从头写 .gitignore 文件,GitHub 已经为我们准备了各种配置文件,只需要组合一下就可以使用了。所有配置文件可以直接在线浏览:https://github.com/github/gitignore。

忽略文件的原则是:

  1. 忽略操作系统自动生成的文件,比如缩略图等;
  2. 忽略编译生成的中间文件、可执行文件等,也就是如果一个文件是通过另一个文件自动生成的,那自动生成的文件就没必要放进版本库,比如 Java 编译产生的 .class 文件;
  3. 忽略你自己的带有敏感信息的配置文件,比如存放口令的配置文件。

如果你想添加被忽略的文件,可以用 -f 强制添加到 Git;或者你发现,可能是 .gitignore 写得有问题,需要找出来到底哪个规则写错了,可以用 git check-ignore 命令检查:

把指定文件排除在 .gitignore 规则外的写法就是 ! + 文件名。


配置别名

配置Git的时候,加上 --global 是针对当前用户起作用的,如果不加,那只针对当前的仓库起作用。

每个仓库的Git配置文件都放在 .git/config 文件中。

当前用户的Git配置文件放在用户主目录下的一个隐藏文件.gitconfig中。

  • 配置命令
1
git config --global alias.<别名> <原名>
  • 配置一个 git last ,让其显示最后一次提交信息
1
git config --global alias.last 'log -1'
  • 查看日志配置别名
1
git config --global alias.lg "log --color --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit"

Git 技巧

  • 使用命令 git add <file> ,注意,可反复多次使用,添加多个文件;

  • 使用命令 git commit -m <message> ,完成提交文件到本地仓库。

  • 要随时掌握工作区的状态,使用 git status 命令。

  • 如果 git status 告诉你有文件被修改过,用 git diff 可以查看修改内容。

  • HEAD 指向的版本就是当前版本,因此,Git允许我们在版本的历史之间穿梭,使用命令 git reset --hard commit_id

  • 穿梭前,用 git log 可以查看提交历史,以便确定要回退到哪个版本。

  • 要重返未来,用 git reflog 查看命令历史,以便确定要回到未来的哪个版本。

  • 每次修改,如果不用git add到暂存区,那就不会加入到commit中。

  • 撤销修改操作:

    • 场景1:当你改乱了工作区某个文件的内容,想直接丢弃工作区的修改时,用命令 git restore <file>
    • 场景2:当你不但改乱了工作区某个文件的内容,还添加到了暂存区时,想丢弃修改,分两步,第一步用命令 git restore --staged <file>,就回到了场景1,第二步按场景1操作。
    • 场景3:已经提交了不合适的修改到版本库时,想要撤销本次提交,回退版本,不过前提是没有推送到远程库。
  • 命令 git rm 用于删除一个文件。如果一个文件已经被提交到版本库,那么你永远不用担心误删,但是要小心,你只能恢复文件到最新版本,你会丢失最近一次提交后你修改的内容

  • 建议的删除操作:

    1. rm 或者鼠标点击的方式删除文件。

    2. 用命令 git rm <file> 确认删除文件。

    3. 用命令 git restore <file> 返回被删除的文件(无论文件修改与否,返回的都是未修改前的文件)。

  • 要关联一个远程库,使用命令 git remote add origin git@server-name:path/repo-name.git

  • 关联一个远程库时必须给远程库指定一个名字, origin 是默认习惯命名;

  • 关联后,使用命令 git push -u origin master 第一次推送master分支的所有内容;

  • 此后,每次本地提交后,只要有必要,就可以使用命令 git push origin master 推送最新修改;

  • 要克隆一个仓库,首先必须知道仓库的地址,然后使用git clone命令克隆。

  • Git支持多种协议,包括https,但ssh协议速度最快。

  • Git鼓励大量使用分支:

    • 查看分支:git branch
    • 创建分支:git branch <name>
    • 切换分支:git checkout <name> 或者 git switch <name>
    • 创建+切换分支:git checkout -b <name> 或者 git switch -c <name>
    • 合并某分支到当前分支:git merge <name>
    • 删除分支:git branch -d <name>
    • 当Git无法自动合并分支时,就必须首先解决冲突。解决冲突后,再提交,合并完成。解决冲突就是把Git合并失败的文件手动编辑为我们希望的内容,再提交。用git log --graph命令可以看到分支合并图。
  • 合并分支时,加上--no-ff参数就可以用普通模式合并,合并后的历史有分支,能看出来曾经做过合并,而fast forward 合并就看不出来曾经做过合并。
  • bug 分支
    • 修复 bug 时,我们会通过创建新的 bug 分支进行修复,然后合并,最后删除;
    • 当手头工作没有完成时,先把工作现场 git stash 一下,然后去修复 bug ,修复后,再 git stash pop ,回到工作现场;
    • 在 master 分支上修复的 bug ,想要合并到当前 dev 分支,可以用 git cherry-pick <commit> 命令,把 bug 提交的修改“复制”到当前分支,避免重复劳动。
  • 开发一个新feature,最好新建一个分支;如果要丢弃一个没有被合并过的分支,可以通过 git branch -D <name> 强行删除。
  • 多人协作
    • 查看远程库信息,使用 git remote -v
    • 本地新建的分支如果不推送到远程,对其他人就是不可见的;
    • 从本地推送分支,使用 git push origin branch-name ,如果推送失败,先用 git pull 抓取远程的新提交;
    • 在本地创建和远程分支对应的分支,使用 git switch -c branch-name origin/branch-name ,本地和远程分支的名称最好一致;
    • 建立本地分支和远程分支的关联,使用 git branch --set-upstream branch-name origin/branch-name
    • 从远程抓取分支,使用 git pull ,如果有冲突,要先处理冲突。
  • rebase 操作可以把本地未 push 的分叉提交历史整理成直线;rebase 的目的是使得我们在查看历史提交的变化时更容易,因为分叉的提交需要三方对比。
  • 标签管理
    • 命令 git tag <tagname> 用于新建一个标签,默认为 HEAD ,也可以指定一个 commit id;
    • 命令 git tag -a <tagname> -m "blablabla..." 可以指定标签信息;
    • 命令 git tag 可以查看所有标签;
    • 命令 git push origin <tagname> 可以推送一个本地标签;
    • 命令 git push origin --tags 可以推送全部未推送过的本地标签;
    • 命令 git tag -d <tagname> 可以删除一个本地标签;
    • 命令 git push origin :refs/tags/<tagname> 可以删除一个远程标签。
  • 在GitHub上,可以任意Fork开源仓库;自己拥有Fork后的仓库的读写权限;可以推送pull request给官方仓库来贡献代码。
  • 忽略某些文件时,需要编写 .gitignore.gitignore 文件本身要放到版本库里,并且可以对 .gitignore 做版本管理!


📌最后:希望本文能够给您提供帮助,文章中有不懂或不正确的地方,请在下方评论区💬留言!