Git FAQ
| 对比维度 | Git | SVN |
|---|---|---|
| 版本库模型 | 分布式,每人都有完整仓库 | 集中式,依赖中央服务器 |
| 分支 | 轻量,几乎免费 | 复制目录,重 |
| 提交速度 | 快,本地提交 | 慢,需要网络 |
| 离线工作 | 完全支持 | 不能 |
| 存储结构 | 内容寻址(对象) | 文件差异 |
| 合并冲突处理 | 强大 | 一般 |
一句话总结:
Git 是分布式的、以内容为核心、分支极快、合并强的现代工具。
- 工作区(working directory):你的代码所在目录。
- 暂存区(stage/index):git add 后进入的区域。
- 本地仓库(repository):.git 目录,存储 commit、tree 对象。
- 远程仓库(origin):GitLab/GitHub 上的仓库。
流程图:
工作区 -> git add -> 暂存区 -> git commit -> 本地库 -> git push -> 远程库
- HEAD:当前在哪个 commit 或分支上
- Index:暂存区快照
- Working Tree:工作区文件
图示:
HEAD -> Index -> Working Tree
| 命令 | 作用 | 是否修改历史 | 是否危险 | 场景 |
|---|---|---|---|---|
| reset | 回滚到旧版本 | 是 | 危险 | 你想重写历史 |
| revert | 生成一个新提交用于“撤销”某次提交 | 否 | 安全 | 已 push 的代码 |
| checkout | 切换分支/恢复文件 | 否 | 安全 | 查看旧代码 |
- fetch:只拉取,不合并(安全)
- pull = fetch + merge
- 也可 pull –rebase
建议:
永远不要直接用 git pull,用:
git pull --rebase
merge
- 会生成一个新的 merge commit
- 保留分支历史
- 历史变复杂
rebase
- 把你的 commit“移动”到最新分支上
- 历史更干净
- 会重写 commit(危险)
原则:
- 已 push 的保持 merge
- 未 push 的可以 rebase
当目标分支没有额外 commit 时:
- master: A -> B
- feature: A -> B -> C
合并只需要移动指针
不会生成 merge commit。
冲突发生于两人同时修改同一代码区域。解决方式:
- 编辑冲突文件
- 删除标记行(«««<, =======, »»»>)
- git add
- git commit
git branch -d feature/a
强制删除(未合并):
git branch -D feature/a
git push origin --delete feature/a
Git 有 4 类对象:
- blob:文件内容
- tree:目录
- commit:包含 tree、作者、时间、父 commit
- tag:指向 commit
commit 是指向 tree 的指针。
- Git 不看修改时间
- Git 看内容 SHA-1 哈希
内容一致 -> 哈希一致 -> 文件视为相同对象 -> 不重复存储
保存当前未提交的修改:
git stash
恢复:
git stash pop
查看:
git stash list
git log -- filename
git blame filename
git diff branch1..branch2
git clone -b develop --single-branch URL
git clone --depth 1 URL
只克隆最新 commit。
用途:CI 节省时间。
说明:
- 当前目录没有 git merge
- 需要 git fetch 和 git merge 的正确顺序
修复:
git fetch origin target-branch
git merge origin/target-branch
优先级从高到低:
- 命令行 -c 设置
- 环境变量 GIT_*
- credential.helper=store(文件)
- 系统级 ~/.git-credentials
git -c credential.helper="store --file=/tmp/cred" push
并且删除默认读取:
git -c credential.useHttpPath=true \
-c credential.helper="store --file=/tmp/cred" \
push
git -c credential.helper= push
或:
git -c credential.helper="store --file=/tmp/cred" \
-c credential.helper= \
push
使用 reflog:
git reflog
git checkout <commit>
git branch recovery
使用 revert:
git revert <commit>
不要用 reset!
git show tagname
git checkout HEAD -- path/file.txt
使用:
git -c credential.helper= -c credential.helper="store --file=/cred" pull
常用查看命令
git status
git log --oneline --graph --decorate
git branch -a
git remote -v
常用合并命令
git merge xxx
git rebase xxx
常用撤销命令
git reset --hard
git revert
git checkout -- file