哪种 SCM/VCS 可以很好地处理文件之间的文本移动?

发布于 2024-08-05 14:48:01 字数 661 浏览 5 评论 0原文

我们在工作中对项目造成了严重破坏,因为当我们跨文件移动信息时,我们的 VCS 正在进行一些糟糕的合并。

场景是这样的:

您有很多文件,比如说,包含有关字典中术语的信息,因此您对字母表中的每个字母都有一个文件。

输入术语的用户盲目地遵循字典顺序,因此如果字典碰巧在 B 下列出了“kick the bucket”(或者它可能同时在 B、bucket 和 K, kick 下列出),他们就会在 B 下放置一个条目。 。

随后,其他用户将这些术语移至其正确的文件中。关于词典术语的大量工作一直在进行。

例如,用户 A 可能已经获取了 B 文件并详细说明了“kick the bucket”条目。用户B拿走了B和K文件,并将“kick the bucket”条目移动到K文件中。无论它们最终按哪个顺序提交,VCS 都可能会丢失条目,并且不会“弄清楚”条目已被移动。

(这些条目稍后会自动转换为 SQL 数据库。但是它们以“人类友好”的形式保存以便对其进行处理,并带有大量注释、示例等。因此,说“让您的用户直接输入 SQL”是不可接受的".)

糟糕的是,我们现在几乎已经开始手动合并这些类型的文件,因为我们无法信任我们的 VCS。 :(

那么解决方案是什么?我很想知道有一个 VCS 可以解决这个问题。或者更好的合并算法?或者,也许有人可以建议更好的工作流程或文件安排来尝试避免这个问题?

We are having havoc with our project at work, because our VCS is doing some awful merging when we move information across files.

The scenario is thus:

You have lots of files that, say, contain information about terms from a dictionary, so you have a file for each letter of the alphabet.

Users entering terms blindly follow the dictionary order, so they will put an entry like "kick the bucket" under B if that is where the dictionary happened to list it (or it might have been listed under both B, bucket and K, kick).

Later, other users move the terms to their correct files. Lots of work is being done on the dictionary terms all the time.

e.g. User A may have taken the B file and elaborated on the "kick the bucket" entry. User B took the B and K files, and moved the "kick the bucket" entry to the K file. Whichever order they end up getting committed in, the VCS will probably lose entries and not "figure out" that an entry has been moved.

(These entries are later automatically converted to an SQL database. But they are kept in a "human friendly" form for working on them, with lots of comments, examples etc. So it is not acceptable to say "make your users enter SQL directly".)

It is so bad that we have taken to almost manually merging these kinds of files now, because we can't trust our VCS. :(

So what is the solution? I would love to hear that there is a VCS that could cope with this. Or a better merge algorithm? Or otherwise, maybe someone can suggest a better workflow or file arrangement to try and avoid this problem?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

遗忘曾经 2024-08-12 14:48:01

我建议:

  • 使用分支(这样,提交的顺序并不重要:每个开发人员在他/她自己的分支中记录他/她自己的一组修改)
  • 将分支合并到主“dico”分支上,其中冲突可以发生已解决

Git 特别擅长于此)


您可以快速测试它:

C:\test\git>mkdir dico
C:\test\git>cd dico
C:\test\git\dico>git init
Initialized empty Git repository in C:/test/git/dico/.git/
C:\test\git\dico>echo words for B> B.txt
C:\test\git\dico>echo words for K> K.txt
C:\test\git\dico>git add -A & git commit -m "first letters"
[master (root-commit) e91d6fa] first letters
 2 files changed, 2 insertions(+), 0 deletions(-)
 create mode 100644 B.txt
 create mode 100644 K.txt

您master 分支中有一个空的 dico。
DevA 出现:

C:\test\git\dico>git checkout -b devA
Switched to a new branch 'devA'
C:\test\git\dico>echo Kick the Bucket: my def from devA>>B.txt
C:\test\git\dico>type B.txt
words for B
Kick the Bucket: my def from devA
C:\test\git\dico>git add -A & git commit -m "def from devA"
[devA 0f27595] def from devA
 1 files changed, 1 insertions(+), 0 deletions(-)

DevB 出现并获得 devA 的工作:

C:\test\git\dico>git checkout master
Switched to branch 'master'
C:\test\git\dico>type B.txt
words for B
C:\test\git\dico>git checkout -b devB
Switched to a new branch 'devB'
C:\test\git\dico>git merge devA
Updating e91d6fa..0f27595
Fast forward
 B.txt |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

C:\test\git\dico>type B.txt
words for B
Kick the Bucket: my def from devA

哦不!这个定义错误的地方!

C:\test\git\dico>echo words for B>B.txt
C:\test\git\dico>echo Kick the Bucket: my def from devA>>K.txt
C:\test\git\dico>git add -A & git commit -m "move def to K by devB"
[devB 473614d] move def to K by devB
 2 files changed, 1 insertions(+), 1 deletions(-)

在 devB 分支中修复。 DevB 继续:

C:\test\git\dico>echo add to def by devB>>K.txt
C:\test\git\dico>git add -A & git commit -m "elaborate def by devB on K"
[devB f9ae17d] elaborate def by devB on K
 1 files changed, 1 insertions(+), 0 deletions(-)

意思是,在 devA 分支中,devA 也处理这个定义:

C:\test\git\dico>git checkout devA
Switched to branch 'devA'
C:\test\git\dico>type B.txt
words for B
Kick the Bucket: my def from devA
C:\test\git\dico>type K.txt
words for K

C:\test\git\dico>echo elabore def from devA in B>>B.txt

C:\test\git\dico>type B.txt
words for B
Kick the Bucket: my def from devA
elabore def from devA in B

C:\test\git\dico>git add -A & git commit -m "devA go on on B.txt"
[devA 1da899a] devA go on on B.txt
 1 files changed, 1 insertions(+), 0 deletions(-)

如果 devB 检查 devA 的工作,他会检测到冲突并适当解决:

C:\test\git\dico>git checkout devB
Switched to branch 'devB'

C:\test\git\dico>git merge devA
Auto-merging B.txt
CONFLICT (content): Merge conflict in B.txt
Automatic merge failed; fix conflicts and then commit the result.

C:\test\git\dico>git diff
diff --cc B.txt
index 1cc6ea9,a986721..0000000
--- a/B.txt
+++ b/B.txt
@@@ -1,1 -1,3 +1,6 @@@
  words for B
++<<<<<<< HEAD
++=======
+ Kick the Bucket: my def from devA
+ elabore def from devA in B
++>>>>>>> devA

他将从 B.txt 中删除额外的定义并将其添加到 K.txt (然后将转到 devA 并告诉他/她停止,合并他的工作,然后继续右侧文件!)

I would recommend:

  • using branching (that way, the order of commit does not matter: each developer records his/her own set of modifications in his/her own branch)
  • consolidate the branches on a main 'dico' branch where the conflicts can be resolved

(Git is especially good at this)


You can test it quickly:

C:\test\git>mkdir dico
C:\test\git>cd dico
C:\test\git\dico>git init
Initialized empty Git repository in C:/test/git/dico/.git/
C:\test\git\dico>echo words for B> B.txt
C:\test\git\dico>echo words for K> K.txt
C:\test\git\dico>git add -A & git commit -m "first letters"
[master (root-commit) e91d6fa] first letters
 2 files changed, 2 insertions(+), 0 deletions(-)
 create mode 100644 B.txt
 create mode 100644 K.txt

You have an empty dico in the master branch.
DevA comes along:

C:\test\git\dico>git checkout -b devA
Switched to a new branch 'devA'
C:\test\git\dico>echo Kick the Bucket: my def from devA>>B.txt
C:\test\git\dico>type B.txt
words for B
Kick the Bucket: my def from devA
C:\test\git\dico>git add -A & git commit -m "def from devA"
[devA 0f27595] def from devA
 1 files changed, 1 insertions(+), 0 deletions(-)

DevB comes along and get the work of devA:

C:\test\git\dico>git checkout master
Switched to branch 'master'
C:\test\git\dico>type B.txt
words for B
C:\test\git\dico>git checkout -b devB
Switched to a new branch 'devB'
C:\test\git\dico>git merge devA
Updating e91d6fa..0f27595
Fast forward
 B.txt |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

C:\test\git\dico>type B.txt
words for B
Kick the Bucket: my def from devA

Oh no! Wrong place for this definition!

C:\test\git\dico>echo words for B>B.txt
C:\test\git\dico>echo Kick the Bucket: my def from devA>>K.txt
C:\test\git\dico>git add -A & git commit -m "move def to K by devB"
[devB 473614d] move def to K by devB
 2 files changed, 1 insertions(+), 1 deletions(-)

Fix in devB branch. DevB goes on:

C:\test\git\dico>echo add to def by devB>>K.txt
C:\test\git\dico>git add -A & git commit -m "elaborate def by devB on K"
[devB f9ae17d] elaborate def by devB on K
 1 files changed, 1 insertions(+), 0 deletions(-)

Meaning, in the devA branch, devA also work on this definition:

C:\test\git\dico>git checkout devA
Switched to branch 'devA'
C:\test\git\dico>type B.txt
words for B
Kick the Bucket: my def from devA
C:\test\git\dico>type K.txt
words for K

C:\test\git\dico>echo elabore def from devA in B>>B.txt

C:\test\git\dico>type B.txt
words for B
Kick the Bucket: my def from devA
elabore def from devA in B

C:\test\git\dico>git add -A & git commit -m "devA go on on B.txt"
[devA 1da899a] devA go on on B.txt
 1 files changed, 1 insertions(+), 0 deletions(-)

If devB checks the devA's work, he will detect the conflict and resolve it appropriately:

C:\test\git\dico>git checkout devB
Switched to branch 'devB'

C:\test\git\dico>git merge devA
Auto-merging B.txt
CONFLICT (content): Merge conflict in B.txt
Automatic merge failed; fix conflicts and then commit the result.

C:\test\git\dico>git diff
diff --cc B.txt
index 1cc6ea9,a986721..0000000
--- a/B.txt
+++ b/B.txt
@@@ -1,1 -1,3 +1,6 @@@
  words for B
++<<<<<<< HEAD
++=======
+ Kick the Bucket: my def from devA
+ elabore def from devA in B
++>>>>>>> devA

He will remove the extra definition from B.txt and add it to K.txt (and then will go to devA and will tell him/her to STOP, merge his work, and go on in the right file!)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文