配置

默认配置在 ~/.gitconfig 文件中,不同项目可以单独进行配置,配置文件在项目目录下的 .gitconfig 文件中。

可以通过 git config [--global] 命令进行配置,也可以直接修改配置文件内容。

  1. 用户名和邮箱

    每一次 commit 都会产生一条 log,这条 log 记录了提交人的姓名与邮箱,执行以下命令配置用户名与邮箱:

     $ git config --global user.name "mapan"
     $ git config --global user.email "mapan1984@outlook.com"
    

    以上进行了全局配置,如果想对某个项目进行特殊配置,只需进入项目目录,执行:。

     $ git config user.name "mapan"
     $ git config user.email "mapan1984@outlook.com"
    
  2. 设置 Editor 使用vim

     $ git config --global core.editor "vim"
    
  3. 终端着色

     $ git config --global color.ui true
    
  4. 设置显示中文文件名

     $ git config --global core.quotepath false
    
  5. 设置 alias

    更好的 log 显示,将 lg 设置为 log 的 alias

     $ git log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit --date=relative
     $ git config --global alias.lg "log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit --date=relative"
    
  6. 提交时把 CRLF 换为 LF

     $ git config --global core.autocrlf input
    
  7. 修改 git diff 算法

     $ git config --global diff.algorithm patience
    
  8. git 为命令输出提供分页器,如果想让某个命令输出直接显示,可以设置 pager

     $ git config --global pager.log false
    
     $ git config --global pager.branch false
    

概念

  1. Working Directory:工作区
  2. Index:暂存区,工作区的修改通过 git add 进入暂存区
  3. Branch:分支,暂存区的修改通过 git commit 进入分支记录
    1. Local Branch:本地分支
    2. Remote Branch:远程分支

命令

修改commit

  1. 修改最后一次 commit 的信息:

     $ git commit --amend
    
  2. reset

    使用 reset 撤销 commit,HEAD~ 可以是任意 commit 位置

     $ git reset --soft HEAD~      # 仅根据 commit 位置移动 HEAD 指针,不恢复 Index 和 Working Directory,即本地和暂存的修改不会丢失
     $ git reset [--mixed] HEAD~   # 根据 commit 位置移动 HEAD 指针,恢复 Index,不恢复 Working Directory
     $ git reset --hard HEAD~      # 根据 commit 位置移动 HEAD 指针,恢复 Index、Working Directory
    
  3. rebase

    修改最近俩次提交记录

     $ git rebase -i HEAD~2
    
  4. reflog

     $ git reflog
    

submodule

  1. 使用 submodule 嵌套已存在库

     $ git submodule add https://github.com/mapan1984/lib.git
    
  2. clone 带有 submodule 的库

    • 直接使用 recursive 参数递归 clone

        $ git clone --recursive https://github.com/mapan1984/Toys.git
      
    • 使用 submodule 的更新功能来获取嵌套的库

        $ git clone https://github.com/mapan1984/Toys.git
        $ git submodule init
        $ git submodule update
      
    • 或者

        $ git clone https://github.com/mapan1984/Toys.git
        $ git submodule update --init
      

远程仓库

添加远程仓库

$ git remote add

远程仓库记录在 .git/config 文件中

查看分支 branch

# 查看远程分支
$ git branch -r

$ git branch -a

HEAD 指当前所在位置,可以为分支名,表示当前分支最新位置,记录在 .git/HEAD

推送本地分支到远程仓库 push

$ git push remote_repo local_branch:remote_branch

# 在本地 reset 了 commit,导致本地分支落后于远程分支,可以强制推送
$ git push --force remote_repo local_branch:remote_branch

# 推送所有 tag
$ git push origin --tags

# refs/for/<branch> 表示经过 code review 之后才可以提交
git push origin HEAD:refs/for/master

fetch 可以拉取远程仓库中的分支代码

# 更新所有 remote repo 上所有 branch 的最新 commit id
$ git fetch

# 更新 remote_repo 上所有 branch 的最新 commit id
$ git fetch remote_repo

# 更新 remote_repo 上 remote_branch 的最新 commit id
$ git fetch remote_repo remote_branch

# 更新 remote_repo 上 remote_branch 的最新 commit id,在本地创建 local_branch 保存 remote_branch 的数据
$ git fetch remote_repo remote_branch:local_branch

FETCH_HEAD 指最新 fetch 的分支,保存在 .git/FETCH_HEAD 文件中。

pull 相当于 fetch + merge

In its default mode, git pull is shorthand for git fetch followed by git merge FETCH_HEAD.

$ git pull remote_repo remote_branch:local_branch

# 相当于

$ git fetch remote_repo remote_branch:local_branch
$ git merge FETCH_HEAD

stash

$ git stash
$ git stash list
$ git stash apply [stash@{n}]
$ git stash drop stash@{n}
$ git stash pop

diff

$ git diff  # 查看工作区与暂存区的区别
$ git diff --staged  # 暂存区与最后一次提交的区别
$ get diff master branchB  # 比较两个提交记录的差别

rebase

变基的实质是丢弃一些现有的提交,然后相应地新建一些内容一样但实际上不同的提交

切换到 experiment 分支,变基到 master 分支

$ git checkout experiment
$ git rebase master

这个操作会将寻找 experiment 与 master 的最近的共同祖先,然后将 experiment 在这之后的所有操作作用到 master 分支上。

$ git rebase [basebranch] [topicbranch]

控制粒度

$ git commit -a

提交之后新增被忽略的文件:

$ git add -N  # notify


$ git add -p  # --patch, 把一次修改分开提交:
$ git checkout -p # --patch
$ git rebase -x npm run tests  # --exec,在rebase的每一阶段执行命令

cherry-pick

$ git cherry-pick <commitHash>

commit offset

HEAD 表示当前所在位置,记录在 .git/HEAD

使用 ~ 向前回溯,只在当前分支选择

使用 ^ 向前回溯,可以在合并树中选择分支,如果当前节点由多个分支合并,^1 也是当前分支,^2 选择第 2 个父分支

使用 @

git diff @^^ @
git diff master@{upstream} master
git diff master@{1} master
git diff master@{yesterday} master

gir rebase -i @~4
git log @^^..@
  • https://stackoverflow.com/questions/2221658/whats-the-difference-between-head-and-head-in-git