背景:我在git门户网站上托管了一个git存储库(即gogs)。有两个分支master
和dev
。我对git
的理解是,一旦我克隆了一个存储库,我可以自由地从一个分支切换到另一个分支,并且当切换到另一个分支时,一个分支中的未提交的更改将被丢弃。但是,此存储库不是这种情况。
这是dev
分支的视图:
如您所见,dist
目录列出了文件401.html
等。
master
分支的视图相同,具体为dist/401.html
。
我的目的是将dist
目录从两个分支移动到我们系统上某个位置的目录。 dev
:
+ git clone http://git.example.com/3DS/mysite.git
Cloning into 'mysite'...
remote: Counting objects: 969, done.
remote: Compressing objects: 100% (516/516), done.
remote: Total 969 (delta 485), reused 857 (delta 431)
Receiving objects: 100% (969/969), 17.29 MiB | 2.35 MiB/s, done.
Resolving deltas: 100% (485/485), done.
Checking connectivity... done.
+ cd mysite
+ git checkout dev
Branch dev set up to track remote branch dev from origin.
Switched to a new branch 'dev'
+ mv dist /tmp/web/dev
我已正确设法创建/tmp/web/dev
,其中包含dist
以及401.html
等所有文件的预期结果。
我现在尝试对分支master
执行相同的操作:
+ git checkout master
(...)
D dist/401.html
D dist/403.html
D dist/404.html
(...)
Switched to branch 'master'
Your branch is up-to-date with 'origin/master'.
+ mv dist /tmp/web/main
/tmp/web/main
的内容几乎没有,只剩下几个文件。 401.html
已消失(其他很多人,D
行很多,我只想修复401.html
上的列表作为示例)
为什么会这样?为什么dist
在一个分支中的移动会影响另一个分支中的dist
?
如何完成上述方案(将dist
从每个分支移动到其自己的文件夹,某处?)
今天我的解决方法是克隆两次,但我想了解我正在犯的错误。
答案 0 :(得分:2)
与您的想法相反,在Git中切换分支不会影响工作目录,除非存在一些冲突,在这种情况下Git甚至不允许您切换分支。
我对你情况的解决方法是:
git checkout dev
mv dist /tmp/web/dev
git add ... # add anything moved not already staged
git commit -m 'moved the dist folder'
git checkout master
# at this point, the dist folder should still be in its original location
mv dist /tmp/web/dev
然后,像git add
分支一样master
并dev
提交。
这里的底线是对分支进行结构更改通常只会影响该特定分支。在尝试切换到另一个分支之前,您应该暂存然后提交此类更改。
答案 1 :(得分:2)
我对
git
的理解是,一旦我克隆了一个存储库,我可以自由地从一个分支切换到另一个分支,并且当切换到另一个分支时,一个分支中的未提交的更改将被丢弃。
这是错的。
如果您进行了一些更改并希望取消所有这些更改,则可以使用git reset --hard
。如果您运行git checkout
,Git将成功并保持所有更改,或者失败。如果您使用git checkout -f
as you suggested in a comment,则可以通过撤消必要的更改(可能不是所有)来完成结帐。
上面的场景应该如何完成(将dist从每个分支移动到自己的文件夹,某处)?
如果要复制存储库外部的某些内容(以便这些内容在存储库中保持不变),那么简单的方法是使用递归副本,而不是{{ 1}}。也就是说,而不是:
mv
你可以使用:
+ cd mysite
+ git checkout dev
Branch dev set up to track remote branch dev from origin.
Switched to a new branch 'dev'
+ mv dist /tmp/web/dev
现在工作树没有变化。对于我自己,我更喜欢这种方法+ cd mysite
+ git checkout dev
Branch dev set up to track remote branch dev from origin.
Switched to a new branch 'dev'
+ cp -R dist /tmp/web/dev
,因为git reset --hard
是一个学习的坏习惯。 : - )