第3章:直接操纵索引
基础知识
Git索引位于<repo>/index,本质是一个复杂的二进制文件。 具体格式参见这里,大概包括以下内容:
路径和文件名
mode
stage数(第6章讨论merge时会用到,正常情况为0)
修改时间
文件大小
(其他标识文件唯一性的信息)
文件内容对应的blob的SHA1
由于直接修改该文件非常复杂,所以本章不介绍Lv0的方案。
如未提前说明,本章所有命令都需要--git-dir和--work-tree。 不过为了避免繁琐的--git-dir和--work-tree,本章所有命令都会在worktree里面执行:
git init .
# Initialized empty Git repository in /root/.git/也就意味着忽略掉--git-dir和--work-tree也能正常工作。读者需要判断哪些命令可以不依赖--work-tree。
添加/修改index
Lv1
Lv2
若想手动改变mode,只需git update-index --chmod +x -- <path>
Lv3
如果想只添加一部分内容,使用git add -p
删除index
Lv2
Lv3
移动index
没有简单办法。 Lv2方法,使用git update-index --cacheinfo无法指定文件stat信息 Lv3方法,使用git mv不仅移动了index还移动了worktree里的文件
查看index
Lv2
(其中0为stage数,正常情况为0)
利用tree更新index
先弄一个tree:
Lv2
Lv3
利用index更新worktree
注意:添加修改都可以,但是无法删除worktree里面多出来的文件。 请参阅本章最后一节(git clean)。
Lv2
Lv3
利用index创建tree
Lv2
注意:当存在非0的stage数时(一般是由git read-tree -m导致的,见第6章),git write-tree会失败
Lv3
注意:
git commit创建tree并创建commit
利用tree更新worktree
Lv1
Lv3
利用tree同时更新index和worktree
Lv2 一步一步来即可
Lv3
注意:git restore --worktree没有对应的旧语法。
详解git restore
git restoregit restore [--source <tree-ish>] [--staged] [--worktree] -- <path>若
<tree-ish>留空:不写
--staged也不写--worktree:<tree-ish>表示index--worktree:<tree-ish>表示index--staged --worktree:<tree-ish>表示index,而--staged被忽略了--staged:<tree-ish>表示HEAD
不写
--staged也不写--worktree则默认--worktree
等价旧语法:
git restore [--worktree] -- <path>=git checkout -f -- <path>git restore --staged --worktree -- <path>=git checkout -f -- <path>git restore [--source <tree-ish>] --staged -- <path>=git reset [<tree-ish>] -- <path>git restore --source <tree-ish> --staged --worktree -- <path>=git checkout -f <tree-ish> -- <path>git restore --source <tree-ish> [--worktree] -- <path>没有等价的旧语法!
交互式修改index
有时候我们希望将一个文件的部分更改放入index中,此时使用git add -p即可。 如果不小心放多了,使用git restore -p即可。(旧语法git reset -p)
将index和worktree中的更改暂存起来以备日后使用
Lv3
只需git stash [pop]:
注意:请一定认真检查git stash的输出! 不要假设git stash总是成功的。 如果git stash没有成功那么你的更改并没有并保存起来!
git stash pop本质是git merge。参见第6章处理冲突。
删除worktree中多出来的文件(git clean)
git clean)警告:该命令十分危险,可能一瞬删掉你的全部心血!
把以下命令的-n换成-f就能真正删掉文件了 (非常危险,请一定先git clean -n看看什么会消失再真的去-f):
总结
Lv1
git update-index --add --cacheinfo <mode>,<SHA1>,<path>
不常用Lv2
git update-index --add [--info-only] -- <path>git update-index --force-remove -- <path>git checkout-index -fu [--prefix=<pf>] -agit checkout-index -fu [--prefix=<pf>] -- <path>
常用Lv2
git update-index --chmod +x -- <path>git ls-files -sgit ls-files -s -- <path>git read-tree [--prefix=<pf>] <tree-ish>git write-tree [--prefix=<pf>]
Lv3
git add -f -- <path>git rm --cached -- <path>git mvgit restore [--source <tree-ish>] [--staged] [--worktree] -- <path>git commitgit stash [pop]git clean -nd [-x|-X] [-- <path>](把-n换成-f就会真的删除,非常危险)
交互式修改index
git add -pgit restore -p
最后更新于
这有帮助吗?