Какие SCM / VCS хорошо справляются с перемещением текста между файлами? - PullRequest
2 голосов
/ 22 сентября 2009

У нас хаос с нашим проектом на работе, потому что наша VCS делает некоторые ужасные слияния, когда мы перемещаем информацию между файлами.

Сценарий таков:

У вас есть много файлов, которые, например, содержат информацию о терминах из словаря, поэтому у вас есть файл для каждой буквы алфавита.

Пользователи, вводящие термины вслепую, следуют порядку словаря, поэтому они будут помещать запись типа «пнуть ведро» под буквой B, если именно в этом словаре и произошло ее перечисление (или она могла быть указана под буквами B, bucket и K). , удар).

Позже другие пользователи перемещают термины в свои правильные файлы. Много работы делается над словарными терминами все время.

например. Пользователь A, возможно, взял файл B и подробно остановился на записи "kick the bucket". Пользователь B взял файлы B и K и переместил запись «Kick the Bucket» в файл K. В каком бы порядке они ни были зафиксированы, VCS, вероятно, потеряет записи, а не «выяснит», что запись была перемещена.

(Эти записи позже автоматически преобразуются в базу данных SQL. Но они хранятся в «удобной для человека» форме для работы с ними, с большим количеством комментариев, примеров и т. Д. Поэтому недопустимо говорить «заставляйте своих пользователей»). введите SQL напрямую ".)

Это так плохо, что мы теперь почти вручную слили файлы такого типа, потому что мы не можем доверять нашей VCS. (

Так в чем же решение? Я хотел бы услышать, что есть VCS, который мог бы справиться с этим. Или лучший алгоритм слияния? Или иначе, может быть, кто-то может предложить лучший рабочий процесс или расположение файлов, чтобы попытаться избежать этой проблемы?

1 Ответ

4 голосов
/ 22 сентября 2009

Я бы порекомендовал:

  • с использованием ветвления (таким образом, порядок фиксации не имеет значения: каждый разработчик записывает свой собственный набор изменений в свою собственную ветку)
  • консолидация ветвей в основной ветке '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

У вас есть пустой дико в мастер ветке.
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 от devA в 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 и скажет ему / ей ОСТАНОВИТЬ, объединить свою работу и перейти в нужный файл!) 1041 *

...