如何在文件夹层次结构中将所有 git 内容向上移动一级?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/7130850/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How can I move all git content one-level up in the folder hierarchy?
提问by Mridang Agarwalla
I have a git repository whose structure looks like:
我有一个 git 存储库,其结构如下所示:
+--repo.git
|
+----+bootstrap.py
+----+buildout.cfg
+----+.gitignore
+----+webapp
|
+---------+manage.py
+---------+modules
+---------+templates
+---------+static
+---------+...
+---------+...
I would like to move the contents of the webapp
folder one level up. My resulting repo should look like:
我想将webapp
文件夹的内容上移一级。我生成的回购应如下所示:
+--repo.git
|
+----+bootstrap.py
+----+buildout.cfg
+----+.gitignore
+----+manage.py
+----+modules
+----+templates
+----+static
+----+...
+----+...
Can I do this by simply moving all the files of the webapp
directory one level up, deleting the empty webapp
directory and then committing the changes? Would this preserve the commit history of the files under the webapp
directory?
我可以通过简单地将webapp
目录的所有文件向上移动一级,删除空webapp
目录然后提交更改来做到这一点吗?这会保留webapp
目录下文件的提交历史吗?
Although a very simple question for many of you, I'd like to be sure. The last thing I'd want is a git soup.
虽然对你们中的许多人来说是一个非常简单的问题,但我想确定一下。我最不想要的是 git 汤。
I tried moving the files but I lost the commit history as git doesn't really handle a move or a rename. I do know that even though it shows up as a new file in the logs, it is still possible to view the commit history for the file using some options in git log
.
我尝试移动文件,但我丢失了提交历史记录,因为 git 并没有真正处理移动或重命名。我确实知道,即使它在日志中显示为一个新文件,仍然可以使用git log
.
From what I've read, the best way to accomplish this would be using git-filter
. I'm not very good with shell or git so could someone tell me what I'd need to execute to do the aforementioned.
从我读过的内容来看,实现这一目标的最佳方法是使用git-filter
. 我对 shell 或 git 不是很好,所以有人可以告诉我我需要执行什么来执行上述操作。
采纳答案by Sumeet Pareek
Just did this, and it is pretty simple actually. The right way to do this is -
就这样做了,实际上很简单。正确的做法是——
git mv repo.git/webapp/* repo.git/.
and then
进而
git rm repo.git/webapp
followed by a
接着是一个
git add *
git commit -m "Folders moved out of webapp directory :-)"
回答by Alex
Another variant of Sumeet's answer - in the repository directory above "webapp" execute following command:
Sumeet 答案的另一个变体 - 在“webapp”上方的存储库目录中执行以下命令:
git mv webapp/* ./ -k
-k - includes files which are yet not under version control, otherwise you get:
-k - 包含尚未受版本控制的文件,否则您会得到:
fatal: not under version control, source=webapp/somefile, destination=somefile
回答by Augusto
The solution you mentioned should work, as git tracks changes based on the hash of the files first and then their location.
您提到的解决方案应该有效,因为 git 首先根据文件的哈希值跟踪更改,然后是它们的位置。
This wont work if as part of moving the file, you change the contents of the files.
如果作为移动文件的一部分,您更改了文件的内容,这将不起作用。
Bottom case, try it, and if it doesn't work, you can revert the changes, before pushing the changes to the master repo :). This is one of the reasons why I really like git.
底部情况,尝试一下,如果它不起作用,您可以在将更改推送到主存储库之前还原更改:)。这也是我非常喜欢 git 的原因之一。
Edit
编辑
I forgot to mention that to see the changes after a rename, you need to use the '--follow' parameter. Check this example
我忘了提到要查看重命名后的更改,您需要使用“--follow”参数。检查这个例子
First, I created a new git repo
首先,我创建了一个新的 git repo
94:workspace augusto$ mkdir gittest
94:workspace augusto$ cd gittest/
94:gittest augusto$ git init
Initialized empty Git repository in /Volumes/Data/dev/workspace/gittest/.git/
Then created a file in folder/test
然后在文件夹/测试中创建一个文件
94:gittest augusto$ mkdir folder
94:gittest augusto$ vi folder/test
94:gittest augusto$ git add folder/test
94:gittest augusto$ git commit -am "added file"
[master (root-commit) 7128f82] added file
1 files changed, 1 insertions(+), 0 deletions(-)
create mode 100644 folder/test
Then moved the file to newfolder/test
然后将文件移动到新文件夹/测试
94:gittest augusto$ mkdir newfolder
94:gittest augusto$ mv folder/test newfolder/
94:gittest augusto$ git add newfolder/test
94:gittest augusto$ git commit -am "moved/renamed file"
[master 4da41f5] moved/renamed file
1 files changed, 0 insertions(+), 0 deletions(-)
rename {folder => newfolder}/test (100%)
And git log --follow newfolder/test
shows the full history (I've added the parameter -p to show more information, such as the path).
并git log --follow newfolder/test
显示完整的历史记录(我添加了参数 -p 以显示更多信息,例如路径)。
94:gittest augusto$ git log --follow -p newfolder/test
commit 4da41f5868ab12146e11820d9813e5a2ac29a591
Author: Augusto Rodriguez <[email protected]>
Date: Sat Aug 20 18:20:37 2011 +0100
moved/renamed file
diff --git a/folder/test b/newfolder/test
similarity index 100%
rename from folder/test
rename to newfolder/test
commit 7128f8232be45fd76616f88d7e164a840e1917d5
Author: Augusto Rodriguez <[email protected]>
Date: Sat Aug 20 18:19:58 2011 +0100
added file
diff --git a/folder/test b/folder/test
new file mode 100644
index 0000000..3b2aed8
--- /dev/null
+++ b/folder/test
@@ -0,0 +1 @@
+this is a new file
I hope this helps!
我希望这有帮助!
回答by JLRishe
I was able to get it to work simply by doing this from the destination folder:
通过从目标文件夹执行此操作,我能够使其正常工作:
git mv webapp/* .
It seems this doesn't work in the Windows shell (fails with an error Bad source
), but it willwork in Windows if you use the Git Bash shell, which expands the *
wildcard.
似乎这在 Windows shell 中不起作用(因错误Bad source
而失败),但如果您使用 Git Bash shell,它会在 Windows 中工作,它扩展了*
通配符。
回答by Ammaroff
in windows you can do the below:
在 Windows 中,您可以执行以下操作:
While you are in the child folder
当您在子文件夹中时
for /f %f in ('dir /b') do git mv %f ../
The result all objects in child folder will be in the parent folder
结果子文件夹中的所有对象都将在父文件夹中
Please note: some errors may raise when you have object in the child folder with name equals to the child folder
请注意:当您在子文件夹中有名称等于子文件夹的对象时,可能会出现一些错误
回答by Nick
If you are using PowerShell you can run this command from your project root and it will place the content of webapp there.
如果你使用 PowerShell,你可以从你的项目根目录运行这个命令,它会将 webapp 的内容放在那里。
Get-ChildItem .\webapp\ | ForEach-Object { git mv $_.FullName .\ }
回答by arupjbasu
In Windows , using Bash , following worked:
在 Windows 中,使用 Bash ,以下工作:
git mv /c/REPO_FOLDER/X_FOLDER/Y_FOLDER/Z_FOLDER/* /c/REPO_FOLDER/X_FOLDER/Y_FOLDER
回答by Philip Oakley
Yes you can simply move the files over. However you do need to tell git that the old files in the webapp folder have gone, that is, git needs to update its index of finished/committed files.
是的,您可以简单地移动文件。但是,您确实需要告诉 git webapp 文件夹中的旧文件已经消失,也就是说,git 需要更新其已完成/已提交文件的索引。
So you can use git add -A .
to make git notice all the changes, or use the git mv <files>
to tell git to do the move itself. See the git mv man page.
因此,您可以使用git add -A .
来让 git 注意到所有更改,或者使用git mv <files>
来告诉 git 自己进行移动。请参阅 git mv 手册页。
--update.
- 更新。
You noted that you thought ".. git doesn't really handle a move or a rename.." - I was also confused at first and hadn't fully understood the way the Index works. On the one hand folk say git only takes snapshots and doesn't track renames, but then you get hit with it 'failing' if you update .gitignore
, or mv
a file, etc. This 'failure' is a confusion about howthe Index works.
您注意到您认为“.. git 并没有真正处理移动或重命名..” - 起初我也很困惑,并没有完全理解索引的工作方式。一方面,人们说 git 只拍摄快照并且不跟踪重命名,但是如果你更新.gitignore
或mv
文件等,你会被它“失败”击中。这种“失败”是关于索引如何工作的混淆。
My visualisation is that the Index/Staging area is a place, like a storyboard wall, where you place a copy of your latest and greatest 'finished' file, including its path, (using git add
), and it is that copy that is committed. If you don't take that copy down from the storyboard wall (i.e. git rm
), then git will continue to commit it, and confusion abounds (see many SO questions...). The Index is also used by git during merge
s in a similar manner
我的可视化是索引/暂存区是一个地方,就像故事板墙一样,您可以在其中放置最新和最伟大的“完成”文件的副本,包括其路径(使用git add
),并且提交的就是该副本。如果你不从故事板墙上取下那个副本(即git rm
),那么 git 将继续提交它,并且混乱比比皆是(参见许多 SO 问题......)。git 也merge
以类似的方式在s期间使用索引
回答by AlBlue
Yes, git will track the changes in past content. It uses hashes of the file's content so regardless of where they are located in the directory structure, they will be the same file.
是的,git 会跟踪过去内容的变化。它使用文件内容的哈希值,因此无论它们在目录结构中的位置如何,它们都是同一个文件。
As a result, you should do the move in one commit, and then fix up any edits in a subsequent commit. That will enable Git to determine the redirection with maximum efficiency, and won't make any difference to the amount of data stored in the repository (since you'd be making those changes anyway).
因此,您应该在一次提交中进行移动,然后在后续提交中修复任何编辑。这将使 Git 能够以最高效率确定重定向,并且不会对存储在存储库中的数据量产生任何影响(因为您无论如何都会进行这些更改)。