git恢复到master版本_git子模块如何还原到提交的版本?

如果我在一个父项目分支中更新子模块,然后切换到同一工作树中的另一个分支,则该子模块引用似乎已被修改。

例如(哈希值可能会有所不同,您可能必须向下滚动代码窗口才能看到所有行):

# create soon to be submodule

mkdir /tmp/example-submodule

cd /tmp/example-submodule

git init

echo a > a

git add a

git commit -m 'm'

cp -r .git /tmp/example-submodule.git

cd /tmp/example-submodule.git

git config --bool core.bare true

cd /tmp

/bin/rm -rf /tmp/example-submodule

git clone file:///tmp/example-submodule.git

#create other project and add sub-module

mkdir /tmp/example-supermodule

cd /tmp/example-supermodule

git init

echo x > x

git add x

git commit -m 'm'

cp -r .git /tmp/example-supermodule.git

cd /tmp/example-supermodule.git

git config --bool core.bare true

cd /tmp

/bin/rm -rf /tmp/example-supermodule

git clone file:///tmp/example-supermodule.git

#update the submodule

cd /tmp/example-supermodule

git submodule add file:///tmp/example-submodule.git example-sub

git commit -a -m'm'

git submodule status

# prints: 189ea25d45618862d0bfcbf5bd995e05ce1c2e4e example-sub (heads/master)

git push

#update the submodule

cd /tmp/example-submodule

echo b > b

git add b

git commit -m 'm'

git push

#create new branch in super module and update submodule to new HEAD

cd /tmp/example-supermodule

git branch otherbranch

git checkout otherbranch

git submodule update --remote

git commit -a -m'm'

git submodule status

# prints: 26f94e59002603475a1ba731104f92e10e88cf6b example-sub (remotes/origin/HEAD)

git push origin otherbranch

#checkout another branch

git checkout master

git status

cat .git/modules/example-sub/HEAD

# prints: 26f94e59002603475a1ba731104f92e10e88cf6b

检出master之后,子模块的哈希将有所不同,就好像其他分支中的更新也影响了master。

如果我克隆超级项目而不是在同一工作树中切换分支:

cd /tmp

git clone --recursive file:///tmp/example-supermodule.git/ other

cd /tmp/other

git submodule status

它显示了在master分支中添加的子模块提交。

某人如何在工作树的分支之间切换,并使子模块的提交与提交时的匹配? 还是在更改分支后如何恢复显示子模块已被修改而该分支中未对其进行修改?

我只是用git 2.9.0复制了这个问题

最后,您需要做的就是找回一个干净的主人:

git submodule update

这会将子模块重置为其master值,并且.git/modules/example-sub/HEAD将具有正确的值

当您再次结帐otherbranch时,将会遇到相同的问题。

右边的gitlink(索引中的特殊条目)将被检出。

但是.git/modules/example-sub/HEAD不会立即更改。

在这两种情况下,这都是因为签出仅修改gitlink,而不修改子模块的内容。

实际上,只有git submodule update会将子模块的内容签出到其记录的gitlink SHA1中。

这样,如果子模块中有正在进行的工作,则不会由父存储库中的签出清除它们。

这是我自己的实验:

C:\Users\vonc\prog\git\tests>mkdir subm

C:\Users\vonc\prog\git\tests>cd subm

让我们创建两个仓库,每个仓库都有一个提交:

C:\Users\vonc\prog\git\tests\subm>git init s

Initialized empty Git repository in C:/Users/vonc/prog/git/tests/subm/s/.git/

C:\Users\vonc\prog\git\tests\subm>git init p

Initialized empty Git repository in C:/Users/vonc/prog/git/tests/subm/p/.git/

C:\Users\vonc\prog\git\tests\subm>cd s

C:\Users\vonc\prog\git\tests\subm\s>git commit --allow-empty -m"first s commit"

[master (root-commit) d11bd81] first s commit

C:\Users\vonc\prog\git\tests\subm\s>cd ..\p

C:\Users\vonc\prog\git\tests\subm\p>git commit --allow-empty -m"first p commit"

[master (root-commit) 10a7044] first p commit

让我们添加s作为p的子模块(父存储库)

C:\Users\vonc\prog\git\tests\subm\p>git submodule add -- ../s

Cloning into 'C:/Users/vonc/prog/git/tests/subm/p/s'...

done.

C:\Users\vonc\prog\git\tests\subm\p>git st

On branch master

Changes to be committed:

(use"git reset HEAD ..." to unstage)

new file:   .gitmodules

new file:   s

C:\Users\vonc\prog\git\tests\subm\p>git commit -m"add p"

[master aa33ba9] add p

2 files changed, 4 insertions(+)

create mode 100644 .gitmodules

create mode 160000 s

现在让我们修改s仓库,向其master分支添加新的提交

C:\Users\vonc\prog\git\tests\subm\p>cd ..\s

C:\Users\vonc\prog\git\tests\subm\s>git commit --allow-empty -m"second s commit"

[master 81e4800] second s commit

C:\Users\vonc\prog\git\tests\subm\s>gl

* 81e4800 - (HEAD -> master) second s commit (1 second ago)

* d11bd81 - first s commit (3 minutes ago)

让我们在父仓库中创建一个新分支

C:\Users\vonc\prog\git\tests\subm\s>cd ..\p

C:\Users\vonc\prog\git\tests\subm\p>git commit --allow-empty -m"second s commit"

C:\Users\vonc\prog\git\tests\subm\p>git checkout -b branch

Switched to a new branch 'branch'

让我们更新子模块,并将其添加到新的分支branch中:

C:\Users\vonc\prog\git\tests\subm\p>git submodule update --remote

remote: Counting objects: 1, done.

remote: Total 1 (delta 0), reused 0 (delta 0)

Unpacking objects: 100% (1/1), done.

From C:/Users/vonc/prog/git/tests/subm/s

d11bd81..81e4800  master     -> origin/master

Submodule path 's': checked out '81e48007afc90aceca16d884d0fdc34074121732'

C:\Users\vonc\prog\git\tests\subm\p>git st

On branch branch

Changes not staged for commit:

(use"git add ..." to update what will be committed)

(use"git checkout -- ..." to discard changes in working directory)

modified:   s (new commits)

no changes added to commit (use"git add" and/or"git commit -a")

C:\Users\vonc\prog\git\tests\subm\p>git add .

C:\Users\vonc\prog\git\tests\subm\p>git commit -m"update s to latest master"

[branch 271a4fb] update s to latest master

1 file changed, 1 insertion(+), 1 deletion(-)

C:\Users\vonc\prog\git\tests\subm\p>cat .git\modules\s\HEAD

81e48007afc90aceca16d884d0fdc34074121732

C:\Users\vonc\prog\git\tests\subm\p>gl

* 271a4fb - (HEAD -> branch) update s to latest master (26 seconds ago)

* f86aab2 - (master) second s commit (2 minutes ago)

* aa33ba9 - add p (3 minutes ago)

* 10a7044 - first p commit (4 minutes ago)

我检出master,右子模块SHA1被检出,但是子模块的内容尚未更改。

C:\Users\vonc\prog\git\tests\subm\p>git checkout master

M       s

Switched to branch 'master'

C:\Users\vonc\prog\git\tests\subm\p>cat .git\modules\s\HEAD

81e48007afc90aceca16d884d0fdc34074121732

C:\Users\vonc\prog\git\tests\subm\p>git st

On branch master

Changes not staged for commit:

(use"git add ..." to update what will be committed)

(use"git checkout -- ..." to discard changes in working directory)

modified:   s (new commits)

no changes added to commit (use"git add" and/or"git commit -a")

如果我要切换回分支branch,状态将是干净的(这是因为子模块s的内容与其记录的gitlink SHA1匹配)

C:\Users\vonc\prog\git\tests\subm\p>git checkout branch

Switched to branch 'branch'

C:\Users\vonc\prog\git\tests\subm\p>git st

On branch branch

nothing to commit, working directory clean

但是在master上,我需要一个submodule update来将子模块s的内容重置为其SHA1:

C:\Users\vonc\prog\git\tests\subm\p>git checkout master

M       s

Switched to branch 'master'

C:\Users\vonc\prog\git\tests\subm\p>git submodule update

Submodule path 's': checked out 'd11bd8132971a18e3e7cd19984cc6ce106478087'

C:\Users\vonc\prog\git\tests\subm\p>cat .git\modules\s\HEAD

d11bd8132971a18e3e7cd19984cc6ce106478087

C:\Users\vonc\prog\git\tests\subm\p>git st

On branch master

nothing to commit, working directory clean

当我结帐branch时,将出现相同的问题:

C:\Users\vonc\prog\git\tests\subm\p>

C:\Users\vonc\prog\git\tests\subm\p>git checkout branch

M       s

Switched to branch 'branch'

C:\Users\vonc\prog\git\tests\subm\p>git st

On branch branch

Changes not staged for commit:

(use"git add ..." to update what will be committed)

(use"git checkout -- ..." to discard changes in working directory)

modified:   s (new commits)

no changes added to commit (use"git add" and/or"git commit -a")

C:\Users\vonc\prog\git\tests\subm\p>git show s

commit 271a4fb6bf79e2524f98dfbd505b2876b0c173a8

Author: VonC

Date:   Sat Jul 9 06:52:57 2016 +0200

update s to latest master

diff --git a/s b/s

index d11bd81..81e4800 160000

--- a/s

+++ b/s

@@ -1 +1 @@

-Subproject commit d11bd8132971a18e3e7cd19984cc6ce106478087

+Subproject commit 81e48007afc90aceca16d884d0fdc34074121732

再次,git submodule update会将子模块s的内容重置为记录在父仓库的分支branch中的SHA1。

感谢您的回答和链接。


版权声明:本文为weixin_39942351原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。