【问题标题】:Simple Git client using JGit has trouble with fetch/pull使用 JGit 的简单 Git 客户端在获取/拉取时遇到问题
【发布时间】:2013-07-05 18:33:21
【问题描述】:

我使用 JGit 实现了一个非常简单的 Git 客户端,它只能做两件事:

  • 将文件添加到存储库中的分支
  • 检索存储库中分支的文件。

客户端不必担心冲突,因为它假定文件永远不会被修改,只会添加或删除。

我的代码如下。 我的问题是, getFile() 中的获取不会从存储库中获取任何更新。如果我将 fetch 替换为 pull 我会得到一个

org.eclipse.jgit.api.errors.InvalidConfigurationException: 没有值 在配置中找到关键的 branch.development.merge

我不确定配置应该是什么样子,但是在执行 main() 之后,它看起来如下所示,我会假设分支“开发”缺少一个条目?

有人可以帮忙吗?

更新代码和配置,问题依旧

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

【问题讨论】:

    标签: git config fetch pull jgit


    【解决方案1】:

    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();
    

    【讨论】:

    • 它似乎没有解决问题(我更新了我现在使用的代码,在你的建议下)。我现在确实在开发分支的配置文件中获得了一个额外的条目,但我仍然没有从 fetch/pull 获得任何更新。我在这些命令的参数化中遗漏了什么吗? .fetch().setRefSpecs() ?
    • 没关系,我忘了在拉命令的末尾添加 .call() 。但是,它甚至不应该在没有拉动的情况下工作,只是一个获取?感谢您的帮助!
    • 不,获取只是更新远程跟踪分支(例如remote/development)。但是您还想更新您的本地分支 (development),这就是 pull 的作用。更具体地说,pull 执行 fetch + merge 或 fetch + rebase(取决于配置),因此您可以删除 fetch 命令。
    猜你喜欢
    • 1970-01-01
    • 2011-12-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多