我有一个小脚本项目,由一个名为“Droid XX-XX-XX”的目录中的五个不同的源文件组成。每次我创建源目录的新备份副本时,我都会将日期放在X中。因此,不同日期大约有15种不同的版本。我想从最早开始将这些中的每一个添加到我的新Git存储库中。
但是我遇到了几个问题。
一个问题是某些文件使用制表符进行缩进,而其他文件则使用空格 - 但即使唯一的区别是制表符与空格问题,Git也会将整行视为不同。如何让Git忽略缩进格式?
另一个问题是某些文件名没有空格而其他文件名之间有空格 - 但Git将它们视为不同的文件。更糟糕的是,有时文件名被改为不同的东西(比如“PatrolPlan”改为“Patrol”),没有真正的理由。当我添加一组新文件时,我怎么能告诉Git即使文件名不同,它实际上只是某个旧文件的新版本?或者更好的是,我可以将其设置为在发生这种情况时自动检测吗?
最后一个问题是,在开发过程中的某些时刻,我们将两个源文件合并为一个,或者将一个文件合并为一个 - 但是Git不会自动检测相似性并推断出发生了什么。我怎么能告诉Git发生了什么?或者更好的是,如何将两个源文件合并或拆分时自动检测?
我意识到问题(2)和(3)是高度相关的。谢谢你的帮助!
答案 0 :(得分:26)
听起来你需要更多的控制和标准化的开发过程。提交更改的人应该是修改文件的人。或者至少提交者应该确切地知道改变了什么。
仔细检查git diff
的输出,并使用-w
标志忽略空格。还有一些选项可以显示一行内的差异。请参阅下面的一行中的Diffs。
请注意,在提交时,您将无法告诉git跳过空格更改。我建议使用GitX(我更喜欢“兄弟”叉子),它允许你在提交前以交互方式丢弃帅哥。
提交时使用描述性消息。例如,如果文件被拆分,请说明。让你的提交变小。如果您发现自己编写了长提交消息,请将提交分解为更小的部分。这样,当您在很长一段时间之后检查日志时,它将更有意义地改变了什么。
一行内的差异
Git有能力在一行中显示“单词”差异。最简单的方法是使用git diff --color-words
。
但是,我喜欢使用diff.wordRegex
配置自定义“单词”的含义。我也喜欢plain
word-diff格式,因为它更清楚地显示了差异的位置(除了使用颜色外,还在变化周围插入括号)。
命令:
git diff --word-diff=plain
以及我在配置中的内容:
[diff]
wordRegex = [[:alnum:]_]+|[^[:alnum:]_[:space:]]+
这个正则表达式将这些视为“单词”:
您必须拥有git
的最新版本才能使用wordRegex
。请参阅git-config
手册页以查看是否列出了该选项。
<强>更新强>
如果您使用git mv
重命名文件(最好使用其他工具或操作系统重命名),您可以看到git检测到重命名。我强烈建议在不对文件内容进行任何编辑的情况下提交重命名。那是因为git实际上并没有存储你重命名的事实 - 它使用一种启发式,根据文件的变化来猜测它是否是同一个文件。在重命名提交期间更改它越少越好。
如果您稍微更改了文件内容,则可以使用-C
参数git diff
和git log
来更难以检测副本并重命名。添加一个百分比(例如-C75%
)以使git对差异更加宽容。百分比表示内容必须被视为匹配的相似程度。
答案 1 :(得分:3)
现在我对Git了解得更多,我可以回答我自己的问题。
最好使用正则表达式进行全局搜索替换,以标准化不同版本项目中所有文件之间的空白,这样当它们按顺序提交时,不需要更改空格提交。话虽这么说,Atlassian SourceTree的diff工具允许你隐藏空白变化,所以至少你不会看到那些。
处理文件名更改的关键是进行只提交文件名称的提交(不要进行任何其他更改)。然后进行提交,其内容发生变化。这样,正常的差异工具不需要大量的启发式和深挖就可以理解已经发生的事情。问题是如果对文件进行太多更改,比如名称和很多内容,那么大多数diff工具会将其视为摘要删除和新文件。 (正确答案中提到)
这是一个更难的,没有什么好办法。如果你将一个文件分成两个,或者合并两个,那么它在diff中就会很难看。尽量不要在进行拆分的同时进行大量更改,以便拆分是一回事,后续更改将是另一回事。
答案 2 :(得分:2)
您将无法使git忽略制表符/空格,因为git会创建每个文件的散列值,如果散列不同,则该文件被视为不同。
Git将树(目录)视为与文件相同;如果他们的内容发生变化,那么他们就是不同的树。
我不认为这些改变是值得担心的;它们发生在任何发展过程中我认为最适合您的方法是使用git 重放您的开发。换句话说,从您的初始版本开始,然后进行必要的更改(就像您最初的那样),git将记住您正在做的事情。
可选:如果要将更改的日期/时间记录为大致原始的更改,那么可以使用--date
git commit
命令行选项告诉git何时更改制成。