2013-07-05 85 views
1

我用JGit實現一個非常簡單的Git客戶端,只能夠做兩件事情:簡單的Git客戶端使用JGit有取故障/拉

  • 將文件添加到一個分支在倉庫
  • 檢索存儲庫中分支的文件。

客戶端不必擔心衝突,因爲它假定文件永遠不會被修改,只會被添加或刪除。

我的代碼如下。 我的問題是,getFile()中的提取不會從存儲庫中獲取任何更新。如果我更換拉取我得到一個

org.eclipse.jgit.api.errors.InvalidConfigurationException:關鍵branch.development.merge沒有價值 在配置中找到

我不知道配置看起來應該是什麼樣子,但是在執行main()後它看起來如下所示,並且我假定分支「development」缺少一個條目?

任何人都可以幫忙嗎?

更新代碼和配置,問題仍然存在

public class GitClient { 

private String remoteRepositoryUI; 
private String localRepositoryPath; 
private Git localGit; 
private UsernamePasswordCredentialsProvider credentialsProvider; 

public GitClient(String remoteRepositoryURI, String localRepositoryPath, 
     String user, String password) { 
    this.credentialsProvider = new UsernamePasswordCredentialsProvider(user, password); 
    this.remoteRepositoryUI = remoteRepositoryURI; 
    this.localRepositoryPath = localRepositoryPath; 
} 

public void addFile(String sourceFilePath, String repositoryFilePath, Branch branch, String message) throws Exception { 
    switchBranch(branch); 
    FileUtils.copyFile(new File(sourceFilePath), 
      new File(this.localRepositoryPath + File.separator + repositoryFilePath)); 
    localGit.add().addFilepattern(repositoryFilePath).call(); 
    localGit.commit().setMessage(message).call(); 
    localGit.push().setCredentialsProvider(this.credentialsProvider).call();   
} 

public File getFile(String repositoryFilePath, Branch branch) throws Exception { 
    switchBranch(branch); 
    return new File(this.localRepositoryPath + File.separator + repositoryFilePath); 
} 

private void switchBranch(Branch branch) throws InvalidRemoteException, TransportException, IOException, GitAPIException { 
    if(!isInitialized()) 
     initialize(branch); 

    boolean branchExists = localGit.getRepository().getRef(branch.toString()) != null; 
    if (!branchExists) { 
     localGit.branchCreate() 
      .setName(branch.toString()) 
      .setUpstreamMode(SetupUpstreamMode.TRACK) 
      .setStartPoint("origin/" + branch.toString()) 
      .call(); 
    } 
    localGit.checkout().setName(branch.toString()).call(); 
    localGit.fetch().call(); 
    localGit.pull(); 
} 

private boolean isInitialized() { 
    return this.localGit != null; 
} 

private void initialize(Branch branch) throws IOException, 
      InvalidRemoteException, TransportException, GitAPIException { 
    boolean localRepositoryExists = true; 
    try { 
     this.localGit = Git.open(new File(this.localRepositoryPath)); 
    } catch(IOException e) { 
     localRepositoryExists = false; 
    } 

    if(!localRepositoryExists) { 
     List<String> branchesToClone = new LinkedList<String>(); 
     for(Branch aBranch : Branch.values()) 
      branchesToClone.add(aBranch.toString()); 
     Git.cloneRepository() 
     // set the branches to clone from remote to local repository 
     .setBranchesToClone(branchesToClone) 
     // set the initial branch to check out and where to place HEAD 
     .setBranch("refs/heads/" + branch.toString()) 
     // provide the URI of the remote repository from where to clone 
     .setURI(this.remoteRepositoryUI) 
     // set local store location of the cloned repository 
     .setDirectory(new File(this.localRepositoryPath)) 
     .call(); 

     this.localGit = Git.open(new File(this.localRepositoryPath)); 
     for(Branch aBranch : Branch.values()) { 
      boolean branchExists = localGit.getRepository().getRef(aBranch.toString()) != null; 
      if (!branchExists) { 
       localGit.branchCreate() 
        .setName(aBranch.toString()) 
        .setUpstreamMode(SetupUpstreamMode.TRACK) 
        .setStartPoint("origin/" + aBranch.toString()) 
        .call(); 
      } 
      localGit.checkout().setName(aBranch.toString()).call(); 
     } 
    } 
} 

public static void main(String[] args) throws Exception { 
    GitClient clientA = new GitClient("URLToRepository.git", 
      "local", "username", "password"); 
    GitClient clientB = new GitClient("URLToRepository.git", 
      "localB", "username", "password"); 

    clientA.addFile("fileA1", "fileA1", Branch.master, "clientA1"); 
    clientB.addFile("fileB1", "fileB1", Branch.master, "clientB1"); 
    clientB.addFile("fileB2", "fileB2", Branch.development, "clientB2"); 
    clientA.addFile("fileA2", "fileA2", Branch.development, "clientA2"); 
    clientA.addFile("fileA3", "fileA3", Branch.master, "clientA3"); 

    File file = clientA.getFile("fileA1", Branch.master); 
    System.out.println(file.getAbsolutePath() + " " + file.exists()); 

    file = clientA.getFile("fileA2", Branch.development); 
    System.out.println(file.getAbsolutePath() + " " + file.exists()); 

    file = clientA.getFile("fileA3", Branch.master); 
    System.out.println(file.getAbsolutePath() + " " + file.exists()); 

    file = clientA.getFile("fileB1", Branch.master); 
    System.out.println(file.getAbsolutePath() + " " + file.exists()); 

    file = clientA.getFile("fileB2", Branch.development); 
    System.out.println(file.getAbsolutePath() + " " + file.exists()); 
} 

} 

配置:

[core] 
    repositoryformatversion = 0 
    filemode = false 
    logallrefupdates = true 
[remote "origin"] 
    url = URLToRepository.git 
    fetch = +refs/heads/*:refs/remotes/origin/* 
[branch "master"] 
    remote = origin 
    merge = refs/heads/master 
[branch "development"] 
    remote = origin 
    merge = refs/heads/development 

回答

3

switchBranch,下面的選項添加到CheckoutCommand

setCreateBranch(true) 

的問題是,這應該只能做一次(如果分支已經存在,將會失敗)。所以不是在一個命令中做,而是單獨的分支創建和結帳:

String branchName = branch.toString(); 
boolean branchExists = localGit.getRepository().getRef(branchName) != null; 
if (!branchExists) { 
    localGit.branchCreate() 
     .setName(branchName) 
     .setUpstreamMode(SetupUpstreamMode.TRACK) 
     .setStartPoint("origin/" + branchName) 
     .call(); 
} 
localGit.checkout().setName(branchName).call(); 
+0

它似乎沒有解決問題(我更新了我現在使用的代碼後,你的意見)。我現在在開發分支的配置文件中獲得了一個額外的條目,但我仍然沒有從提取/拉取任何更新。我在這些命令的參數化中錯過了什麼嗎? .fetch()。setRefSpecs()? – hansi

+0

沒關係,我忘了在我的pull命令結尾添加.call()。但是,它不應該沒有拉動,只是一個抓取?謝謝您的幫助! – hansi

+0

不,取回只更新遠程追蹤分支(例如'remote/development')。但是你也想更新你的本地分支('development'),這就是pull的作用。更具體地說,pull會執行一個fetch + merge或者fetch + rebase(取決於配置),所以你可以刪除fetch命令。 – robinst