2016-09-27 107 views
1

我在編程上使用JGit lib找到兩個提交之間的差異。diff如何在JGit中處理合並提交

假設我有以下承諾層次:

---1---2---3---4---5---6---7---8-- 
     \--9-—10—-11--/ 

現在,讓我們說我分析diff進行提交4 - 7,如何將diff命令指的是合併在6? 它會保存與先前提交(4之前)相關的信息,例如2?

我用下面的代碼來確定進行比較:

private static List<DiffEntry> getDiffsBetweenCommits(String repositoryWorkDir, String fromCommit, String toCommit) { 
    List<DiffEntry> diffs = null; 
    try { 

     // Access GIT repository 
     File workDir = new File(repositoryWorkDir); 
     Git git = Git.open(workDir); 
     repository = git.getRepository(); 

     // Locate commit references 
     ObjectId current = repository.resolve(toCommit + "^{tree}"); 
     ObjectId previous = repository.resolve(fromCommit + "^{tree}"); 

     // Generate tree iterators 
     ObjectReader reader = git.getRepository().newObjectReader(); 
     CanonicalTreeParser oldTreeIter = new CanonicalTreeParser(); 
     oldTreeIter.reset(reader, previous); 
     CanonicalTreeParser newTreeIter = new CanonicalTreeParser(); 
     newTreeIter.reset(reader, current); 

     // Calculate GIT differences 
     diffs = git.diff() 
       .setNewTree(newTreeIter) 
       .setOldTree(oldTreeIter) 
       .call(); 
    } catch (Exception e) { 
     System.out.println("Error analyzing commit's diffs"); 
     e.printStackTrace(); 
    } 
    return diffs; 
} 

據我得到的文件中是遠遠超過4年長提交改變,我懷疑我得到他們,因爲合併的/重新塑造歷史,但我不太瞭解,所以我可以向自己解釋。

感謝您理解差異分析邏輯的幫助。

回答

0

你可能會更好的改寫/這個問題,把它放在更一般的Git上下文中。

儘管如此,我知道的主題是:與其他SCM不同,Git存儲提交的完整內容,而不僅僅是對父提交的差異。每個提交引用一個所謂的「樹」,它列出了提交中的所有文件以及指向相應文件內容的指針。

創建提交時,會取其父代的樹,應用所有分階段更改(添加,修改,移除),並將生成的(新)樹與提交元數據一起存儲。關於其內容,每一次提交都可以在不參考其父母的情況下進行重構。

讓我們假設您的示例中的每個提交添加了一個唯一的文件。如果你看第6個提交,它包含所有從1到6的文件,加上那些9,10,11。因此,'git diff 4 6'將比較提交#4的樹和提交#6的樹(其中包括迄今爲止歷史中的所有文件)。

想了解更多關於Git中存儲內部信息的細節,您可能需要閱讀這篇文章:http://www.codeaffine.com/2014/10/20/git-internals/該帖子附帶了自包含的學習測試,用於檢查JGit的結果。