这个问题是在设计另一个Git .dotfiles管理系统时出现的。我希望使用$HOME作为我的工作树,并将存储库存储在其他地方(而不是在.git下,因为这会混淆其他存储库)。
在以前复制过并可能被修改过的dotfile的旧机器上,我现在想克隆我的新的dotfiles存储库,并且(挥手)进入一个状态,在那里我可以看到我的$HOME/.* dotfiles的(预)存在状态,作为对我新克隆的存储库的主库的修改。这主要是背景,在Git中,我只想谨慎地签出不覆盖的脏目录。
(在普通情况下,我可以从一个新目录开始,然后复制我的更改,但当工作树是我的$HOME时,这似乎很难做到。)
我找到了一对命令,这些命令似乎把我带到了正确的位置,但我不确定这种方法是否存在缺陷,或者是否有更简单的方法来做同样的事情:
git read-tree -v HEAD # load HEAD into the index
git checkout-index -a # cautiously check out all files without overwriting这两个命令是否达到了复制我家、进行普通签出、然后复制回我的文件的相同状态,这样git diff就会有我在这台机器上所做的更改而没有文件被删除?
对于这些问题,是否还有其他的选择应该适用?
上下文是我的(alpha)引导脚本:
git clone --bare -n git://github.com/$(git config github.user)/.dotfiles.git ~/.dotfiles/repo.git
git config -f .dotfiles/repo.git/config core.bare false
git config -f .dotfiles/repo.git/config core.logallrefupdates true
git config -f .dotfiles/repo.git/config core.worktree $HOME
export GIT_DIR=~/.dotfiles/repo.git ; export GIT_WORK_TREE=~
git read-tree -v HEAD
git checkout-index -a # all files without overwriting
ln -sf $HOME/.dotfiles/gitignore-dots $HOME/.dotfiles/repo.git/info/exclude发布于 2012-07-30 22:14:44
我希望使用$HOME作为我的工作树,并将存储库存储在其他地方(而不是在.git下,因为这会混淆其他存储库)。
不要这样做。我所做的就是
把你的工作树放在这里
/opt/dotfiles把你的回购品放在这里
/opt/dotfiles/.git然后可以通过运行$HOME将工作树引导到
. /opt/dotfiles/bootstrap.sh著名的例子,还有我这里的例子
发布于 2012-08-19 02:41:16
更新2012-08-19
我已经使用这个方案在新的和现有的帐户上设置我的dotfile有一段时间了,上面的命令到目前为止还没有销毁任何东西。另一方面,没有一位git专家对这一安排表示赞同,有些专家含糊地说:“你疯了吗?”有点像。
现在我有了别名doton/dotoff和调整GIT_DIR和GIT_WORK_TREE的源文件,所以我在工作中做了一些调整,尝试了一下,然后推到github,然后在家里更新我的其他机器。大多数情况下,这是一个简单的快速转发或重基,但偶尔需要一个脏的更新。
脏更新
我在这里补充这一点,因为这是问题中描述的方法的另一半。
比如说,我把我的~/.x组合加起来,然后推它。当我想把它拉到已经有.XCompose文件的机器上时,我想要获取更改,请查看本地(未添加)副本的差异,然后从那里合并。Git对此进行检查并保释出去,这通常是合适的。
同样,我使用管道命令来执行大部分较高级别的命令,但不需要进行一些烦人的安全检查,以便使用脏的工作副本。管道命令在文档中没有很好地覆盖,但似乎工作正常(不能保证)。
这些说明假定您没有新的本地更改,即。它不会做任何调整。
(请注意,这可能最终会破坏文件,包括未跟踪的文件。我不知道这是否接近安全,我怀疑如果出了什么问题,你可能会被弄得一团糟。)
git fetch # download FETCH_HEAD
# Check HEAD is an ancestor of FETCH_HEAD
cmp <( git rev-parse HEAD ) <( git merge-base HEAD FETCH_HEAD ) \
|| echo "merge-base is not HEAD, not fast forward"
# merge FETCH_HEAD into HEAD in index (2 tree merge is ff, no local changes)
# (no -u means the work tree is not updated)
git read-tree -v -m HEAD FETCH_HEAD # --trivial ?
# index now merged with FETCH_HEAD
# set HEAD to be FETCH_HEAD with dereferencing
git update-ref HEAD FETCH_HEAD
# update work tree without overwriting existing files (not forced)
# (existing un-added isn't overwritten)
git checkout-index -a
# can now check diffs for conflicts add either commit/edit/checkout
git diff --stat
git pull -vn # should be a no-op下面是一些用于检查事物状态的命令:
git rev-parse HEAD FETCH_HEAD # what do they point to
git diff --stat HEAD FETCH_HEAD # differences
git merge-base HEAD FETCH_HEAD # common ancestor
for r in HEAD FETCH_HEAD; do echo $r ; git log --oneline $r | head -1; done
git name-rev $( git merge-base HEAD FETCH_HEAD )
# peek at index
git ls-files --directory --exclude-standard --stage
git diff-index --cached FETCH_HEAD # see "local changes" carried forwardhttps://stackoverflow.com/questions/10258988
复制相似问题