2009-06-02 27 views
5

Chúng tôi có một thiết lập SVN với thân cây ổn định và chi nhánh phát triển không ổn định. Dev công việc là (chủ yếu) được thực hiện trên các chi nhánh và sau đó sáp nhập vào thân cây trước khi triển khai.Làm thế nào để đánh lừa git-svn để nhận ra các hợp nhất được thực hiện với svn?

Tôi sử dụng git-svn làm ứng dụng SVN của mình. Quá trình hợp nhất của tôi từ không ổn định đến thân cây như sau:

git svn fetch 
git co -b trunk svn/trunk 
git merge --no-ff svn/unstable 
git svn dcommit 

svn/* là các chi nhánh SVN từ xa.

Điều này tất nhiên yêu cầu không ai cam kết bất cứ điều gì với thân cây trước khi tôi hoàn thành, nhưng đây không phải là một vấn đề trong thực tế.

Lợi ích của quá trình này là git giờ ghi lại phụ huynh của hợp nhất cam kết trong kho lưu trữ cục bộ của tôi. Điều này không có lợi cho đồng nghiệp của tôi, nhưng nó cho phép git tính toán tổ tiên chung khi I thực hiện hợp nhất. Điều này là rất mong muốn.

Và đây là chà. Khi một người khác làm cho một hợp nhất, git không biết về nó. Dưới đây là một ví dụ:

o-...-A---o---C--- unstable 
/
X--...--B---o---o--- stable 

Các chi nhánh không ổn định đã được tạo ra vào thời điểm X. Tại điểm A chúng tôi quyết định hợp nhất thay đổi từ chi nhánh không ổn định vào nhánh ổn định vào thời điểm B. tổ tiên chung là đúng X.

Vì hợp nhất không được ghi lại trong lịch sử git, việc hợp nhất sau tại C lại giả định X là tổ tiên chung. Tôi muốn nó là A, như trong biểu đồ sau:

o-...-A---o---C--- unstable 
/  \ 
X---...---B---o---o--- stable 

Nó không hoàn toàn cần thiết để có được một biểu đồ trông giống như hình. Bất kỳ biểu đồ nào, mà sẽ nhận ra A là tổ tiên chung là tốt của tôi.

Tôi có một số tùy chọn trong tâm trí, chẳng hạn như sử dụng hợp lý git-filter-branch hoặc cam kết "giả mạo" vốn không bao giờ bị SVN gây ra. Tuy nhiên không có nỗ lực của tôi đã làm việc đủ cho đến nay.

Tôi biết ơn đối với bất kỳ ý tưởng nào bạn có thể trình bày. Quy trình này không phải là tự động. Sự kết hợp khá hiếm và tôi có thể sống với nỗi đau khi làm điều đó "bằng tay".

Trả lời

2

Một giải pháp thay thế khác là sử dụng tệp Ghép, cho phép bạn ghi đè phụ huynh của cam kết mà không thực sự thao tác lịch sử.

Điều này có nghĩa là sau khi bạn thấy hợp nhất trong kho SVN, bạn chỉ cần thêm một dòng vào .git/info/grafts với các SHA-1 của cam kết hợp nhất (M) và cha mẹ của nó (A, B).

 o-...-A---o---D--- unstable 
    /  
    X-----B---M---o---o--- stable 

A = 31423cd8a838f984547a908777308d846043cbda 
B = d99cfccb1f859a8f1dbfac95eec75227fe518b23 
M = 13319a54d3e3d61b501e7cc6474c46f37784aaa3 

Để tạo liên kết từ AM, bạn sẽ xác định cha mẹ M là B và A. Các định dạng của tập tin ghép là khá đơn giản:

commit newparent1 ... newparentN 

Điều này có nghĩa bạn thêm dòng sau (khá dài) cho tệp ghép của bạn:

13319a54d3e3d61b501e7cc6474c46f37784aaa3 d99cfccb1f859a8f1dbfac95eec75227fe518b23 31423cd8a838f984547a908777308d846043cbda 

Git giờ đây sẽ giả vờ rằng quá trình hợp nhất này thực sự xảy ra. Nhược điểm, điều này không được truyền bá thông qua git push/fetch/clone, nhưng đây không phải là vấn đề lớn cho sự phát triển cá nhân.

+0

Cảm ơn! Đây là lần đầu tiên tôi nghe nói về ghép. Luôn luôn tốt để tìm hiểu thêm. –

2

Vấn đề của bạn là một chút như SVN populating svnmergeinfo from git merges ngược lại:
Bạn không muốn SVN để ghi lại hòa trộn từ Git, nhưng Git để ghi kết hợp từ SVN;)

Kể từ git-svn không quan tâm về svnmergeinfo thuộc tính khi nhập khẩu từ SVN, để lại tùy chọn "hoạt động thủ công".

Tôi sẽ không đề xuất giải pháp git-filter-branch hoặc bất kỳ thứ gì ghi đè lịch sử ở phía Git.
Nếu bạn nhận thấy một "A->B" hợp nhất trên SVN, bạn nên làm điều đó hợp nhất trên Git ** trong một nhánh "hợp nhất", và sau đó hợp nhất nó trở lại vào nhánh ổn định (hợp nhất tầm thường tại điểm này), do đó thêm một cam kết mới vào lịch sử ổn định hiện tại của bạn.

o-.....-A---o---C--- unstable 
/  \ 
/   o-------\__ merge recorder branch 
/  /  \ 
X---.....---B---o---o---o__ stable 

Sau đó, hợp nhất từ ​​C đến ổn định phải có A làm tổ tiên chung.

+0

Đúng vậy! Vì vậy, điều quan trọng là để thực hiện các cam kết trung gian _two_, một trong số đó cũng kết thúc trong SVN là tốt. Điều này dường như làm việc ít nhất trên giấy. Cảm ơn vì thông tin! Tôi tự hỏi nếu nó có thể bóp nó vào một bí danh git ... –

+0

Bạn quên kết thúc "**" (in đậm) trong "... Git ** trong một nhánh" hợp nhất "..." –

0

Xem ra với tệp ghép.

  1. Do họ sai và một gc git sẽ (sau một thời gian) thả bộ phận của lịch sử
  2. Nếu bạn đẩy đến máy chủ khác, nó sẽ không biết về các mô ghép và có thể kết thúc với lịch sử bị phá vỡ.
Các vấn đề liên quan