git 使用记录

git 技巧

git-tips

git 开发流程

git-flow
github-flow

忽略文件

仓库下的 .gitignore 支持正则匹配, 在提交时忽略指定的文件.

基本使用

git status [-s/--short]

git diff
git diff --staged
git diff --cached

git log
git log -p -2
git log --stat

git status # 有很多提示信息

# 取消暂存文件
git reset HEAD file

# 撤销文件修改
git checkout -- file

打包

将分支 branchA 打包:

git archive --format tar.gz --output /tmp/project-v0.1.tar.gz branchA                   # 解压后所有文件解压到指定目录(没有指定则为当前目录);
git archive --format tar.gz --prefix project/ --output /tmp/project-v0.1.tar.gz branchA # 解压后所有文件解压到指定目录的 project 子目录;

git 中 HEAD 表示特殊的指针, 指向当前所在的本地分支.

默认分支

通过 git clone 获取的分支默认命名为 origin/master, origin 表示远程分支的名字, master 为远程分支的指针, git 会创建一个与 origin 的 master 分支指向同一个地方的本地分支. 通过 git clone -o other 获取远程仓库的时候, 默认的远程分支名字则为 other/master.

提交

可以将最新的修改追加到最近一次的提交中, 也可以修改最近一次的提交注释:

git commit --amend

取消 git add

如果想取消刚刚加进暂存区域的文件, 可以使用以下命令将其重新放入未暂存的区域:

git reset filename.txt

如果想取消 git add ., 可以使用以下命令:

git reset

推送分支

推送本地的 serverfix 分支到远程 origin 的 serverfix 分支:

git push origin serverfix
git push origin serverfix:serverfix

推送本地的 serverfix 分支到远程 origin 的 newfix 分支:

git push origin serverfix:newfix

分支切换

切换时, 工作目录中的文件会被改变. 如果切到较旧的分支, 工作目录会恢复到该分支最后一次提交时的状态. 如果当前分支存在修改的文件而没有暂存或提交, git 将禁止切换分支.

跟踪分支

跟踪分支是与远程分支有直接关系的本地分支. 如果在一个跟踪分支上输入 git pull, git 能自动地识别去哪个服务器上抓取, 合并到哪个分支. 在 clone 一个仓库时, 通常会自动地创建一个跟踪 origin/mastermaster 分支. 使用以下命令创建跟踪分支:

git checkout --track origin/serverfix      # 本地创建 serverfix
git checkout -b sf origin/serverfix        # 本地创建 sf 分支

上述设置后, 通过 git pull 即可自动从 origin/serverfix 拉取更新. 使用 -u--set-upstream-to 可以修改上游远程分支:

git branch -u origin/serverfix

合并

切换并合并指定的 commit:

git checkout master
git cherry-pick 62ecb3  #仅合并 62ecb3 的 commit

合并远程的分支 serverfix 到本地分支 serverfix:

git checkout -b serverfix origin/serverfix

也可以将当前更改追加到某个commit上(同2只有细微区别)

① git stash 保存工作空间的改动
② git rebase <指定commit的父commit> --interactive
③ 将需要改动的commit前面的pick 改为 edit,然后保存退出
④ git stash pop

之后的步骤和2一样  
⑤ git add <更改的文件> 
⑥ git commit --amend 
⑦ git rebase --continue 

分支回退

回退当前分支:

git checkout branchname
git reset --soft HEAD^    # 回退一个 commit
git reset --soft HEAD~3   # 回退三个 commit

git reset --soft 9e5e6a4...  # 可能所有分支都会回退到此提交处

拉取分支数据

git fetch  # 仅抓取本地没有的数据, 让开发者自己合并, 不会修改工作目录的内容;
git pull   # 相当于 git fetch + git merge, 会查找当前分支所跟踪的远程分支, 拉取后合并到本地分支;

删除分支

# 删除本地分支, -D 强制删除
git branch -d branchname
git branch -D branchname

# 删除远程的分支
git push origin --delete branchname

如果删除的分支和已有的 tag 同名, 则需要指定具体的路径:

push 同名

object path
branch refs/heads/branch_name
tag refs/tags/tag_name

可以通过以下命令获取远程引用的完整列表:

git ls-remote

如下所示, 如果分支 v0.1tag v0.1 同名, 可以指定路径 push:

git push  origin :refs/heads/v0.1

rebase 变基

整合来自不同分支的修改主要有 mergerebase 两种方式, 使用 rebase 命令将提交到某一分支上的所有修改都移至另一分支上. 最终结果所指向的快照始终是一样的, rebase 使历史提交更加整洁, 是将一系列提交按照原有次序依次应用到另一分支上, merge 则是将最终结果合在一起.

如下所示, ex 分支从 master fork 而来并做了提交修改. 通过以下方式即可将不同分支的提交历史应用到 master 分支中:

# rebase 会提取 ex 相对 master 的变更并存为临时文件, 并改变 ex 的基底 
git checkout ex
git rebase master

# 合并 ex 到 master
git checkout master
git merge ex

备注: 不要对在仓库外有副本的分支执行变基.