在将大量重命名应用于大型项目(略低于10,000个文件)后,使用我的Git历史遇到了很多麻烦。我已将文件从Project/src/....
移至Project/src/main/java/....
,从而更改了项目布局。我还在同一次提交中修改了一些移动的文件。
让我们来看一个这样的文件:
$ git logc PINSSUserPasswordUtil/src/main/java/ca/gc/agr/pinss/userPasswordUtil/UserPasswordReseter.java
* commit 6e7a960f99b0e6164d2713a4cbca2107034d8bbd
Author: moffats <moffats@ec78347f-1a2b-0410-964c-a7254f1fcdc6>
Date: Thu Apr 23 21:24:30 2015 +0000
merge gradle branch to the trunk
好的,看起来我们需要使用--follow
告诉Git关注重命名:
$ git logc --follow PINSSUserPasswordUtil/src/main/java/ca/gc/agr/pinss/userPasswordUtil/UserPasswordReseter.java
...
* commit 6e7a960f99b0e6164d2713a4cbca2107034d8bbd
| Author: moffats <moffats@ec78347f-1a2b-0410-964c-a7254f1fcdc6>
| Date: Thu Apr 23 21:24:30 2015 +0000
|
| merge gradle branch to the trunk
|
...
* commit ce0c98d4b78e2f006ead16a030b3c5f0d7ec3ac0
Author: perches <perches@ec78347f-1a2b-0410-964c-a7254f1fcdc6>
Date: Thu Mar 22 21:29:41 2012 +0000
Updates for JSF 2.0 upgrade
我们走了。现在让我们比较两个版本:
$ git diff -M -l0 ce0c98d4b78e2f006ead16a030b3c5f0d7ec3ac0..HEAD PINSSUserPasswordUtil/src/main/java/ca/gc/agr/pinss/userPasswordUtil/UserPasswordReseter.java
diff --git a/PINSSUserPasswordUtil/src/main/java/ca/gc/agr/pinss/userPasswordUtil/UserPasswordReseter.java b/PINSSUserPasswordUtil/src/main/java/
new file mode 100644
index 0000000..acc4d40
--- /dev/null
+++ b/PINSSUserPasswordUtil/src/main/java/ca/gc/agr/pinss/userPasswordUtil/UserPasswordReseter.java
@@ -0,0 +1,186 @@
+package ca.gc.agr.pinss.userPasswordUtil;
+
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.sql.Connection;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.Map.Entry;
+import java.util.Properties;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
... etc ...
Git显然没有检测到重命名。它找不到文件的旧位置,并告诉我整个文件内容已添加。
请注意,它将现有文件与/dev/null
进行比较,而不是旧文件路径,应该是:
PINSSUserPasswordUtil/src/ca/gc/agr/pinss/userPasswordUtil/UserPasswordReseter.java
好的,我们来看看重命名的提交内容如下:
$ git show --stat=180 6e7a960f99b0e6164d2713a4cbca2107034d8bbd | grep UserPasswordReseter
PINSSUserPasswordUtil/src/{ => main/java}/ca/gc/agr/pinss/userPasswordUtil/UserPasswordReseter.java | 10 +-
这看起来不错,所以这就是我被困住的地方。我可以获得差异的唯一方法是明确告诉Git过去的旧文件路径是什么:
$ git diff ce0c98d4b78e2f006ead16a030b3c5f0d7ec3ac0:PINSSUserPasswordUtil/src/ca/gc/agr/pinss/userPasswordUtil/UserPasswordReseter.java HEAD:PINSSUserPasswordUtil/src/main/java/ca/gc/agr/pinss/userPasswordUtil/UserPasswordReseter.java
-- a/ce0c98d4b78e2f006ead16a030b3c5f0d7ec3ac0:PINSSUserPasswordUtil/src/ca/gc/agr/pinss/userPasswordUtil/UserPasswordReseter.java
+++ b/HEAD:PINSSUserPasswordUtil/src/main/java/ca/gc/agr/pinss/userPasswordUtil/UserPasswordReseter.java
@@ -29,18 +29,18 @@ public class UserPasswordReseter {
private static final Log log = LogFactory.getLog(UserPasswordReseter.class);
private static final String DATASOURCE_BEAN_NAME = "dataSource";
- private static final String USER_PROPERTIES = "configuration/users.properties";
+ private static final String USER_PROPERTIES = "/users.properties";
现在我得到了我想要的东西。
那为什么我以前的'git diff -M -l0
'命令不起作用?我认为这个问题也会导致Eclipse中的EGit和'git instaweb
'这样的工具不再起作用,这意味着我失去了使用强大的GUI工具访问预重命名历史记录的能力。
我不确定如何解决这个问题。任何建议,将不胜感激。
git version 1.9.1
编辑:正如评论中所指出的,这个命令:
git diff -M -l0 ce0c98d4b78e2f006ead16a030b3c5f0d7ec3ac0..HEAD PINSSUserPasswordUtil/src/main/java/ca/gc/agr/pinss/userPasswordUtil/UserPasswordReseter.java
不起作用,b / c我们需要在整个存储库上运行diff,以便重命名检测工作。所以像这样的命令可以正常工作:
$ git diff -M -l0 ce0c98d4b78e2f006ead16a030b3c5f0d7ec3ac0 HEAD
当然,现在我需要在整个提交的大差异输出中查找我感兴趣的文件,但它确实省去了必须键入旧路径和新路径的麻烦。仍然远非理想,但比以前更好。
答案 0 :(得分:2)
重命名检测在计算上非常昂贵(参见下一段),因此git将其限制为您配置的任何内容。如果你没有配置一个特定的值,git内置的默认值在各种版本中都有所增加(100,然后是200,现在是400)。
特别是,在比较任何两个修订版(或更确切地说,两个树)时,出现在&#34; old&#34;中的路径名称。树而不是&#34; new&#34;树提供了重命名的源候选文件,以及出现在&#34; new&#34;中的路径名。树而不是&#34; old&#34;树提供重命名的目标候选者。要检测实际的重命名,git必须将每个可能的源与每个可能的目标进行比较。
据我所知,git(目前)没有&#34;重命名的目录,文件名的尾部是相同的&#34;启发式减少列表的大小。如果这样做会对这里有很多帮助。没有它,您可以使用-l
选项git diff
或diff.renameLimit
配置变量,尝试将重命名限制设置得非常高(根据需要设置多个路径名)。将其设置为明确的0
意味着&#34;无限制&#34; (内部实际上是32767,因此并不完全无限制。)