如何在不克隆的情况下使用 JGIT 将文件夹添加到 GitHub 存储库?
How do I add a folder to a GitHub repo using JGIT without cloning?
如何使用 JGIT 将包含项目的文件夹添加到存储库(在本例中为 GitHub 存储库)而无需克隆等?我是否可以只使用该文件夹创建一个本地存储库,然后将其与远程存储库合并?
我不想克隆的原因是存储库会变得非常大,我不希望克隆需要很长时间。此外,这是在 Spigot 插件命令中,但我认为这不会改变任何东西。当我 运行 命令时它给我一个错误。
最后一件事是当我将文件夹复制到 repo 文件夹时。它只是创建一个名为“Minecraft Servers”的文件夹和其中的文件 none。我做错了什么?
源代码:
public class SaveServer implements CommandExecutor {
private final CrucialPlugin plugin;
public SaveServer(CrucialPlugin plugin) {
this.plugin = plugin;
}
@Override
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
if (sender instanceof Player) {
Player player = (Player) sender;
if (args.length == 0) {
player.sendMessage(ChatColor.RED + "You need to enter some arguments");
player.sendMessage(ChatColor.YELLOW + "To save the server network to the GitHub repo: /saveserver <what you built/did>");
} else if (args.length == 1) {
if (plugin.getConfig().getString("Repository URL") != null && plugin.getConfig().getString("GitHub username") != null && plugin.getConfig().getString("GitHub password") != null) {
Path repofolder = Path.of("Server Network Repo");
File test = new File(String.valueOf(repofolder));
if (Files.exists(repofolder)) {
test.delete();
}
player.sendMessage(ChatColor.GREEN + "Saving server with caption: " + args[0] + "...");
File curdir = new File(System.getProperty("user.dir"));
Path networkFolder = curdir.toPath().getParent();
Path finalFolder = Path.of(repofolder + File.separator + "Minecraft Servers");
Date date = new Date();
char subColon = '\uA789';
String filename = date.toString().replace(':', subColon) + "-" + args[0].toUpperCase().replace("_", " ") + ".txt";
File txt = new File(networkFolder + File.separator + filename);
try {
txt.createNewFile();
Git.init().setDirectory(new File("Server Network Repo")).call();
Git git = Git.open(new File("Server Network Repo"));
git.add().addFilepattern(networkFolder.toString()).call();
Files.copy(networkFolder, finalFolder, REPLACE_EXISTING);
// add remote repo:
RemoteAddCommand remoteAddCommand = git.remoteAdd();
remoteAddCommand.setName("origin");
remoteAddCommand.setUri(new URIish(plugin.getConfig().getString("Repository URL")));
remoteAddCommand.call();
// push to remote:
PushCommand pushCommand = git.push();
pushCommand.setCredentialsProvider(new UsernamePasswordCredentialsProvider(plugin.getConfig().getString("GitHub username"), plugin.getConfig().getString("GitHub password")));
pushCommand.call();
} catch (GitAPIException | IOException | URISyntaxException e) {
player.sendMessage(ChatColor.RED + "Unable to retrieve repository.");
}
player.sendMessage("Filename test: " + filename);
} else {
player.sendMessage(ChatColor.RED + "You need to fill in all the fields under Save Server in the configuration file before you can use this feature.");
}
} else {
player.sendMessage(ChatColor.RED + "Too many arguments");
player.sendMessage(ChatColor.YELLOW + "To save the server network to the GitHub repo: /saveserver <what you built/did>");
}
}
return true;
}
}
问题似乎可以通过使用浅克隆和稀疏签出来解决,这些 git 功能允许克隆存储库而无需实际提取全部内容和历史记录。问题是截至 2022 年 4 月,该功能尚未在 jGit 中实现。因此,根据您的情况,您可能会做出某种妥协:
如果您可以控制将要执行代码的环境,您可以尝试调用 shell 命令并调用真正的 git 而不是 jgit。这当然会降低解决方案的可移植性,并给环境带来额外的配置负担,(期望安装 git,期望它的版本正确,期望代码 运行 权限足以调用系统命令,git 身份验证现在发生在 Java 代码之外,等等)。
如果您打算只将特定的更新文件推送到主分支的顶部,并且您不关心所有 git 功能,如分支、差异和合并,而只是使用非常具体的 github 存储库作为一种配置存储,有时您需要使用 Java 进行更新,那么您可能希望完全跳过 git,并使用 Github REST API 代替。然后,您将发送更新后的文件和提交信息,例如作为 http POST 请求的消息和作者,并让 Github 将其转换为其他用户可以使用常规 git 的提交] 客户。 API 已经准备好使用 Java 包装器,例如this project。当然,如果你只是碰巧使用了Github,而实际的代码预计会与anygit仓库和服务器后端一起工作,那么这个方法将不会工作。它也有对 API 产生额外依赖的缺点,它不像常规 git 那样稳定,因此由于 Github 的变化,某些东西更有可能被破坏。
从另一个角度解决问题,尽量减少存储库的大小。例如,放弃 git 历史并使每个提交都成为一个修改提交强制推送以覆盖前一个。可能是 git 反模式列表中的前 10 项,并且明显滥用了 git 的意图,但如果它解决了您的问题,那么这一切都是最好的。没有解决存储库大文件大的问题,不仅仅是因为历史悠久。
-
如何使用 JGIT 将包含项目的文件夹添加到存储库(在本例中为 GitHub 存储库)而无需克隆等?我是否可以只使用该文件夹创建一个本地存储库,然后将其与远程存储库合并?
我不想克隆的原因是存储库会变得非常大,我不希望克隆需要很长时间。此外,这是在 Spigot 插件命令中,但我认为这不会改变任何东西。当我 运行 命令时它给我一个错误。
最后一件事是当我将文件夹复制到 repo 文件夹时。它只是创建一个名为“Minecraft Servers”的文件夹和其中的文件 none。我做错了什么?
源代码:
public class SaveServer implements CommandExecutor {
private final CrucialPlugin plugin;
public SaveServer(CrucialPlugin plugin) {
this.plugin = plugin;
}
@Override
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
if (sender instanceof Player) {
Player player = (Player) sender;
if (args.length == 0) {
player.sendMessage(ChatColor.RED + "You need to enter some arguments");
player.sendMessage(ChatColor.YELLOW + "To save the server network to the GitHub repo: /saveserver <what you built/did>");
} else if (args.length == 1) {
if (plugin.getConfig().getString("Repository URL") != null && plugin.getConfig().getString("GitHub username") != null && plugin.getConfig().getString("GitHub password") != null) {
Path repofolder = Path.of("Server Network Repo");
File test = new File(String.valueOf(repofolder));
if (Files.exists(repofolder)) {
test.delete();
}
player.sendMessage(ChatColor.GREEN + "Saving server with caption: " + args[0] + "...");
File curdir = new File(System.getProperty("user.dir"));
Path networkFolder = curdir.toPath().getParent();
Path finalFolder = Path.of(repofolder + File.separator + "Minecraft Servers");
Date date = new Date();
char subColon = '\uA789';
String filename = date.toString().replace(':', subColon) + "-" + args[0].toUpperCase().replace("_", " ") + ".txt";
File txt = new File(networkFolder + File.separator + filename);
try {
txt.createNewFile();
Git.init().setDirectory(new File("Server Network Repo")).call();
Git git = Git.open(new File("Server Network Repo"));
git.add().addFilepattern(networkFolder.toString()).call();
Files.copy(networkFolder, finalFolder, REPLACE_EXISTING);
// add remote repo:
RemoteAddCommand remoteAddCommand = git.remoteAdd();
remoteAddCommand.setName("origin");
remoteAddCommand.setUri(new URIish(plugin.getConfig().getString("Repository URL")));
remoteAddCommand.call();
// push to remote:
PushCommand pushCommand = git.push();
pushCommand.setCredentialsProvider(new UsernamePasswordCredentialsProvider(plugin.getConfig().getString("GitHub username"), plugin.getConfig().getString("GitHub password")));
pushCommand.call();
} catch (GitAPIException | IOException | URISyntaxException e) {
player.sendMessage(ChatColor.RED + "Unable to retrieve repository.");
}
player.sendMessage("Filename test: " + filename);
} else {
player.sendMessage(ChatColor.RED + "You need to fill in all the fields under Save Server in the configuration file before you can use this feature.");
}
} else {
player.sendMessage(ChatColor.RED + "Too many arguments");
player.sendMessage(ChatColor.YELLOW + "To save the server network to the GitHub repo: /saveserver <what you built/did>");
}
}
return true;
}
}
问题似乎可以通过使用浅克隆和稀疏签出来解决,这些 git 功能允许克隆存储库而无需实际提取全部内容和历史记录。问题是截至 2022 年 4 月,该功能尚未在 jGit 中实现。因此,根据您的情况,您可能会做出某种妥协:
如果您可以控制将要执行代码的环境,您可以尝试调用 shell 命令并调用真正的 git 而不是 jgit。这当然会降低解决方案的可移植性,并给环境带来额外的配置负担,(期望安装 git,期望它的版本正确,期望代码 运行 权限足以调用系统命令,git 身份验证现在发生在 Java 代码之外,等等)。
如果您打算只将特定的更新文件推送到主分支的顶部,并且您不关心所有 git 功能,如分支、差异和合并,而只是使用非常具体的 github 存储库作为一种配置存储,有时您需要使用 Java 进行更新,那么您可能希望完全跳过 git,并使用 Github REST API 代替。然后,您将发送更新后的文件和提交信息,例如作为 http POST 请求的消息和作者,并让 Github 将其转换为其他用户可以使用常规 git 的提交] 客户。 API 已经准备好使用 Java 包装器,例如this project。当然,如果你只是碰巧使用了Github,而实际的代码预计会与anygit仓库和服务器后端一起工作,那么这个方法将不会工作。它也有对 API 产生额外依赖的缺点,它不像常规 git 那样稳定,因此由于 Github 的变化,某些东西更有可能被破坏。
从另一个角度解决问题,尽量减少存储库的大小。例如,放弃 git 历史并使每个提交都成为一个修改提交强制推送以覆盖前一个。可能是 git 反模式列表中的前 10 项,并且明显滥用了 git 的意图,但如果它解决了您的问题,那么这一切都是最好的。没有解决存储库大文件大的问题,不仅仅是因为历史悠久。