git

1 基础

初级教程命令总结文档Pro Git 2ndPro Git 2nd(网页版)

  1. git 特点分布式,不必联网。建议文本 UTF-8 编码
  2. 安装 linux上 apt-get 或者 源码, windows版本
  3. 设置全局的用户名和邮箱,设置代理,初始化
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    git config --global user.name "Your Name"
    # 不设置 email
    git config --global user.email '<>'
    # 支持中文路径和文件名
    git config --global core.quotepath false
    # 编辑器设为 vi
    git config --global core.editor "vi"
    # 查看设置
    git config --list
    git config --global core.autocrlf false
    # 提交简写
    git config --global alias.ac '!git add -A && git commit -m'
    # HTTP 代理
    git config --global http.proxy http://127.0.0.1:17890
  4. git pull 默认取所有分支,–all 取所有 remote。git push 默认当前分支,–all 所有分支
  5. 代理,只用 ssh 协议。参考
    1
    2
    3
    4
    5
    6
    7
    8
    Host github.com
    Hostname ssh.github.com
    IdentityFile C:\Users\XXX\.ssh\id_ed25519
    User git
    Port 443
    ProxyCommand "D:\soft\Git\mingw64\bin\connect.exe" -S 127.0.0.1:17890 %h %p
    Host *
    IdentityFile C:\Users\XXX\.ssh\id_rsa

1.1 图形工具

参考 best-three-way-merge-tool,使用 p4merge 和 meld

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
sudo apt-get install meld
git config --global diff.tool meld
# 官网注册下载
# 使用手册 https://www.perforce.com/manuals/p4merge/Content/P4Merge/Home-p4merge.html
sudo ln -s /home/zack/bin/p4v-2019.1.1830398/bin/p4merge /usr/local/bin/p4merge
git config --global merge.tool p4merge
cat ~/.gitconfig

# 可以选择关闭
git config --global difftool.prompt false

# windows 下的配置,User/用户名/.gitconfig,注意路径斜杠用 /
# 设置 meld 的字体时选择 Yahei Consolas Hybrid,指定英文字体时会因为没有中文字符显示乱码
[http]
proxy = socks5://127.0.0.1:17890
[user]
email = <>
name = Jian-Feng Du
[core]
quotepath = false
[diff]
tool = meld
[difftool]
prompt = true
[difftool "meld"]
cmd = "\"D:/soft/Meld/Meld.exe\" \"$LOCAL\" \"$REMOTE\""

受限于网速时可用 vimdiff

1.2 查看修改和历史

  • git diff 比较的是工作区与暂存区的差异,git diff HEAD -- readme.txt 用来比较工作区与分支的差异,git diff --cached 比较暂存区与分支差异
  • commit 的几种表示法详见 Revision-Selection
1
2
3
4
5
6
7
8
9
10
# 查看历史提交
git log --pretty='%C(yellow)%h%Creset %C(green)%cd%Creset %C(blue)%d%Creset %s' --date=format:%m-%d --graph 1.1.1^..HEAD
git config --global alias.lg "log --pretty='%C(yellow)%h%Creset %C(green)%cd%Creset %C(blue)%d%Creset %s' --date=format:%m-%d --graph"
# 找到第一个 commit
git rev-list --max-parents=0 --pretty HEAD
# 查看历史修改的文件列表
git diff-tree --no-commit-id --name-only -r bd61ad98
# 某个文件的历史修改
git log -p -- filename
# 也可以使用脚本 diff_hist.sh 见资源

1.3 改写历史

Rewriting-History

git merge 和 git rebase 都是先切换到目标分支,然后指定源分支的方式

1
2
# 把一个提交应用到多个分支上
git cherry-pick <commit id>

1.4 回到过去

Reset and checkout

HEAD Index Workdir WD Safe?
Commit Level
reset --soft [commit] REF NO NO YES
reset [commit] REF YES NO YES
reset --hard [commit] REF YES YES NO
checkout <commit> HEAD YES YES YES
File Level
reset [commit] <paths> NO YES NO YES
checkout [commit]/index <paths> NO YES/NO YES NO
1
2
3
# 使用远端还原本地
git fetch
git checkout origin/dev -- src_comm/tiny_config.c

1.5 加快下载

1
2
3
4
5
6
7
8
9
10
11
# shallow clone,可以不把全部的 commit 和 branch 都下载下来,节省下载时间
git clone --depth=1 url
git clone --depth=1 --single-branch --branch branch url
git fetch --unshallow
git fetch --depth=200
# https://stackoverflow.com/questions/6802145/how-to-convert-a-git-shallow-clone-to-a-full-clone
git config remote.origin.fetch "+refs/heads/*:refs/remotes/origin/*"
git fetch origin

# 下载失败可以尝试修改
git config --global http.postBuffer 524288000

2 用 subtree 管理库

3 问题

3.1 多个远端仓库

只要远端不同,同一公钥可以用在多处仓库,只有在同一网站(比如 github)上有多个账号时需要配置多个 key

3.1.1 生成新 key

  1. 按照 git配置多个SSH Key ,其中命令可以指定文件名 ssh-keygen -t rsa -b 4096 -C "another_mail@qq.com" -f id_rsa_github
  2. 页面上添加对应公钥

3.1.2 添加 remote

1
2
git remote add origin https://github.com/user/repo.git
git remote -v
  • 给 pull 和 push 设定不同的 remote 方法,这样设置的典型用途 (同一回答)

3.1.3 设置 track 分支

track-remote-upstream-branch

1
2
3
4
5
6
7
8
9
10
# Set upstream when pushing to remote
git push -u origin topic

# Set upstream without pushing it
# with option -u / --set-upstream-to
git branch -u origin/topic
git branch --set-upstream-to=origin/topic

# 验证
cat .git/config

3.2 个人代码同步

对未改完的代码提交一个临时的 commit,两端都基于这个 commit 来改代码(使用 commit –amend)和同步,已经修改完成则将 commit message 修改或 rebase 整理历史。

参考 git-pull-after-forced-update,两端都按下面步骤进行

  1. 取回使用 git pull --rebase 来更新另一端的提交
  2. 修改代码
  3. 改写历史 git rebase -i HEAD~~ 或合并到最近的历史 git commit --amend
  4. 更新提交历史 git push -f

3.3 删除分支

3 种情况,远端、本地、本地的 track 分支 Delete Git branch locally and remotely

3.4 查找谁引入的问题