0%

Git 工具个人总结

Git 是一款免费开源的分布式版本控制系统工具, 以下是我在日常或工作使用时总结的 Git 常用命令。


目录

基本概念

img

  • 工作区/工作目录(Workspace/Working Directory): 就是你平时存放项目代码的目录。
  • 暂存区(Stage/Index):用于临时存放你的改动,事实上它只是一个文件,保存即将提交到文件列表信息, 一般存放在 “.git目录下” 下的index文件(.git/index)中,所以我们把暂存区有时也叫作索引(index)。
  • 仓库区/版本库(Repository/Git Directory):就是安全存放数据的位置,这里面有你提交到所有版本的数据。其中HEAD指向最新放入仓库的版本。
  • 远程仓库(Remote Directory):gitee.com

一般文件 Git 操作流程:

  • 通过 vim REDEME.md 更改 工作区 文件内容。
  • 通过 git add 命令将 工作区 文件添加到 暂存区(Index/Stage)
  • 通过 git commmit 命令提交到 仓库区
  • 通过 git push 命令推送到 远程仓库

安装

  • Windows
  • Mac: brew install git
  • Git 可视化工具 - 适用于 Mac & Windows 平台
    • sourcetree 相比 fork 卡、中文菜单、Bug?
    • fork

      配置

      Git 全局配置, 默认 Git 配置信息存储在用户目录即: ~/.gitconfig 文件中。
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      git config --global user.name "codezm"
      git config --global user.email "codezm@163.com"

      # 配置 - 保存账号及密码至本地 ~/.git-credentials,仅第一次手动录入账号及密码
      git config --global credential.helper store
      # macOS
      # git config --global credential.helper osxkeychain
      # windows
      # git config --global credential.helper wincred
      # 密码更换
      # git config --global --unset user.password
      # 开启行尾结束符自动转换,默认值是:false,crlf (Windows默认模式) to *unix lf 模式。
      git config --global core.autocrlf true
      # 配置 - 全局忽略文件, 默认文件不存在自行新建文件即可
      git config --global core.excludesfile ~/.gitignore
      # git 使用外部工具合并冲突后避免生成多余的 .orig 备份文件
      git config --global mergetool.keepBackup false

      # 查看 Git 配置信息。
      git config --list
      vim ~/.gitconfig
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      [user]
      name = codezm
      email = codezm@163.com
      [credential]
      helper = store
      [core]
      excludesfile = ~/.gitignore
      editor = vim
      [mergetool]
      keepBackup = false
      [alias]
      co = checkout
      lg = log --graph --pretty=format:'%Cred%h%Creset - %C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit --date=relative

忽略文件

  • Git 全局忽略规则配置文件,应用于所有 Git 项目,配置文件路径可使用命令 git config core.excludesfile 查看 ––– 默认不存在需配置。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    $ vim `git config core.excludesfile`

    ####################################
    ######## OS generated files ########
    ####################################
    .DS_Store
    .DS_Store?
    *.swp
    ._*
    .Spotlight-V100
    .Trashes
    Icon?
    ehthumbs.db
    Thumbs.db
    ####################################
    ############# packages #############
    ####################################
    *.7z
    *.dmg
    *.gz
    *.iso
    *.jar
    *.rar
    *.tar
    *.zip
    # Compiled source #
    ###################
    *.com
    *.class
    *.dll
    *.exe
    *.o
    *.so
    *.pyc

    # Logs and databases #
    ######################
    *.log
    *.sqlite
  • Git 忽略规则配置文件: .gitignore,在单个 Git 项目下创建仅适用于此项目。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    # 忽略项目中所有 log 文件夹(/runtime/log、/log):
    log
    # 忽略项目根路径下整个 runtime 文件夹:
    /runtime/*

    # 但排除 runtime 根文件夹下某个文件:
    !/runtime/wechat-post-data.log

    # 注意: 若想排除以下文件是无效的。
    # !/runtime/pid/swoole/master.pid
    # 解决方案,这也是 `忽略某个文件夹,但又不想忽略这个文件夹下的某个子目录`的解决方案。
    !/runtime/pid
    /runtime/pid/*
    !/runtime/pid/swoole
    /runtime/pid/swoole/*
    !/runtime/pid/swoole/master.pid

    # 检查 UI-Images.zip 文件被哪个忽略规则所匹配:
    git check-ignore -v /tags/UI-Images.zip

    # 忽略规则强制添加至 Git 版本库:
    git add -f /tags/UI-Images.zip
  • .gitkeep 文件的作用

    Git 默认是不允许提交一个空目录到版本库的,可以在空的文件夹里面建立一个 .gitkeep 文件,然后提交去即可。其实在 Git.gitkeep 就是一个占位符。

    示例: 需要 Git 提交 Yaf - views 空目录。

    仓库

  • 基于远程项目克隆至本地

    首先,gitee 创建远端「 remote 」仓库: git-demo,然后克隆至本地目录:

    1
    2
    3
    cd ~
    git clone https://gitee.com/codezm/git-demo.git git-demo
    cd git-demo
  • 基于本地项目创建 git 仓库

    1
    2
    3
    4
    5
    6
    cd <project>
    git init
    git remote add origin https://gitee.com/codezm/git-demo.git
    git add .
    git commit -m 'First commit.'
    git push origin master
  • 修改本地项目 git 仓库地址

    1
    2
    cd <project>
    git remote set-url origin <origin-url>

分支

新 Git 项目默认 ( git clone ) 所在分支为: master

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# 查看本地所在分支,带 * 表示当前所在分支.
git branch
# 查看远程所有分支
# git branch -r
# 查看所有分支, 包含本地和远程服务器
git branch -a

# 创建分支
git branch <branch-name>
# 创建一个空分支
# git checkout --orphan emptybranch
# 示例 - 于 master 分支基础上创建 dev 分支: git branch dev
# 创建并检出至一个新分支
git checkout -b <branch-name>

# 分支切换,切换至 dev 分支
git checkout <branch-name>

# 删除本地分支
git branch -d <branch-name>

# 分支重命名
# git branch -m <old-branch-name> <new-branch-name>

# 删除远程服务器分支
# git push origin --delete <branch-name>
# git push origin :<branch-name>

注意: 本地分支删除时需要先切换至其他分支再操作要删除的分支。

提交

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 编辑工作区项目代码.
echo "test git" > README.md

# 提交至暂存区.
git add README.md
# 遍历询问是否添加 - 仅限已添加至 Git 项目文件,新增文件排除。
# git add -p
# 添加工作目录所有新增/改动文件
# git add .

# 提交至本地仓库区.
git commit -m 'Modify README.md'

# 提交至远端仓库 - 只有提交后他人才可使用你提交的代码.
git push origin master
# -u 设置 origin 为默认主机, 之后就可以直接使用 git push 推送至远程服务器。
# 默认只推送当前分支: simple方式。Git 2.0版本之前,默认采用matching方法, 会推送所有有对应的远程分支的本地分支
git push -u origin master

查看

  • 查看哪些文件改动了?「 git add 前查看 」

    1
    git status
  • 工作区文件. 「 git 文件差异对比 」

    1
    2
    3
    4
    git diff

    # 对比某一文件差异
    # git diff <file-name>
  • 暂存区文件: git add. 「 git 文件差异对比 」

    1
    2
    3
    4
    git diff --cached

    # 对比某一文件差异
    git diff --cached <file-name>
  • 版本库文件: git commit. 「 git 文件差异对比 」

    1
    2
    3
    4
    5
    6
    7
    8
    9
    # 查看此 <COMMIT-ID> 所有文件更改详情.
    git show <COMMIT-ID>
    # 示例-仅查看指定文件: git show a09ce4377cd292 README.md
    # 示例-使用某次COMMIT文件内容: git show 0cc28f7194a19b3303c2cf:README.md

    # 对比两次 <COMMIT-ID> 的文件更改详情.
    # git diff <COMMIT-ID>...<COMMIT-ID> README.md
    # 对比两次 <COMMIT-ID> 涉及的所有文件名
    # git diff <COMMIT-ID>...<COMMIT-ID> --name-only

    github - 对比视图 | 示例

  • 修改了哪些文件?「 git commit 后查看 」

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    git log --stat

    # git show <COMMIT-ID> --name-only

    # 展示最后一次提交修改的文件
    # git log --stat -n 1
    # 查看<文件>commit历史, 展示 <commit-id> <comment-message>
    # git log --oneline <filename>
    # 查看某个文件的历史改动
    # git blame <filename>

    拉取

  • git fetch 是将远程主机的最新内容(所有远程仓库的 branch、tag)拉到本地,用户在检查了以后决定是否合并到工作本机分支中。

  • git pull 则是将远程主机的最新内容拉下来后直接合并,即:git pull = git fetch + git merge

    1
    2
    3
    4
    git pull origin/master

    # git fetch
    # git merge origin/master

合并

1
2
3
4
5
6
7
8
git checkout dev
# git pull 有个前提当前分支 dev 对应远程分支 origin/dev 已存在,此处也可使用: git fetch
git pull
git merge origin/kakaguo
# 若存在冲突则解决完冲突后还需要执行以下操作:
# git add .
# git commit -m ''
git push origin dev

撤销/回滚

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# 非 Git 项目管理文件撤销「 删除 」, 即: 不在 git 版本控制下的新增文件
rm -f README.md

# 新增文件撤销
git rm --cached NEW_README.md

# 工作区文件撤销「 还原 」
git checkout -- README.md

# 暂存区文件撤销「 取消 git add 操作 」
git reset HEAD README.md

# 本地仓库文件撤销 「 取消 git commit 操作 」
git log

## 重置 HEAD 和索引
#### 此时若是又修改了 README.md 文件再执行 git reset 后文件 README.md 内容会展示什么?
git reset <COMMENT-ID> 等价于 git reset --mixed <COMMENT-ID>
## 重置 HEAD、索引和工作区, 会重置以下工作区域文件: - 执行此操作是危险的。
## 1. 对 README.md 所有操作丢弃.
## 2. 若工作区对 README.en.md 做了修改但未 git commit, 即使 git add 到了暂存区也会被丢弃。
git reset --hard <COMMENT-ID>

# 远程仓库撤销: 主要用于撤销已 push 的 commit 操作,即 git commit -> git push -> git reset -> git push -f
git push -f

冲突解决

分支 hanlu、kakaguo 同时修改 README.md 文件.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
git checkout hanlu
echo 'hanlu' > README.md
git add .
git commit -m 'Modify README.md by hanlu.'
git push -u origin hanlu

git checkout kakaguo
echo 'kakaguo' > README.md
git add .
git commit -m 'Modify README.md by kakaguo.'
git push

git checkout dev
git pull
git merge origin/hanlu
git push origin dev
git merge origin/kakaguo
# 解决冲突
git add .
git commit -m 'Merge kakaguo'
git push origin dev

# 撤销合并「 注意: 仅在合并失败(快速合并失败被阻止)时执行 」, 以下命令对工作区代码无影响:
# git reset --merge
# git merge --abort

Tag

打标签、项目版本管理.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# 创建 Tag
git tag <tag-name>
# 示例 - 创建 1.0.0 版本Tag: git tag v1.0.0

# 显示所有 Tag
git tag

# 加上 -l 命令可以使用通配符来过滤tag
# git tag -l "1.0.*"

# 给 <commit-id> 加 Tag 并添加备注信息.
# git tag -a <tag-name> <commit-id> -m <comment-message>

# 显示 Tag 详情: 显示 <commit-id>、Tag 备注信息等
# git show <tag-name>

# 推送至远程仓库
# git push origin <tag-name>
# 推送本地所有 Tag
git push origin --tags

# 切换至某个 Tag, 与分支类似
git checkout <tag-name>

# 删除本地某个 Tag
# git tag -d <tag-name> <tag-name-mores>

# 删除远程仓库 Tag
# git push origin --delete tag <tag-name>
# git push origin :refs/tags/<tag-name>

Stash - 贮藏

适用场景: 临时合并他人分支存在 - 同时更改相同文件、分支可能存在冲突。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
git stash

# 保存 stash 并设置名称,simple 方式: git stash
# git stash save <message>

# 仅还原
# git stash apply

# 删除指定 stash
# git stash drop stash@{0}

# 还原并删除 stash, git stash apply + git stash drop
git stash pop

# 列出所有 stash
# git stash list

注意: git stash pop 如果存在冲突文件将导致 drop 失败。

结语

  1. 每次 git push 前,先拉取下 git pull origin master / git pull origin dev 代码。
  2. 仅merge部分文件:git rebase -i
  3. 仅stash部分文件: git stash -p
  4. 批量还原: git status | grep “修改” | awk ‘{print $2}’ | grep -v “git” | xargs git checkout –
  5. 批量删除: git status | grep “/“ | grep -v “origin/master” | xargs rm -rf