Compare commits

...

2 Commits

Author SHA1 Message Date
6a532322c4 Add credential settings
All checks were successful
Deploy / build (push) Successful in 55s
2026-02-27 19:22:38 +01:00
52fe455c76 Add ahead/behind indicator and push/pull buttons 2026-02-27 19:22:03 +01:00
6 changed files with 56 additions and 6 deletions

View File

@@ -52,6 +52,10 @@ environment variables / command-line arguments):
|---|---|
| `webgit.worktree-path` | Path to the shared network drive where working trees are stored (the files your retro machines will access). |
| `webgit.git-dir-path` | Path where `.git` directories are stored (can be a local disk on the server). |
| `webgit.username` | Username for push/pull authentication (e.g. a dedicated Gitea account). |
| `webgit.password` | Password or access token for push/pull authentication. |
Credentials can be supplied via environment variables (`WEBGIT_USERNAME`, `WEBGIT_PASSWORD`) to avoid storing them in config files.
Example:

View File

@@ -16,4 +16,6 @@ public class WebgitProperties
private Path worktreePath;
private Path gitDirPath;
private Integer telnetPort;
private String username;
private String password;
}

View File

@@ -57,6 +57,12 @@ public class RepoController
model.addAttribute("branch", gitService.getCurrentBranch(name));
model.addAttribute("modifiedFiles", gitService.getModifiedFiles(name));
model.addAttribute("stagedFiles", gitService.getStagedFiles(name));
int[] aheadBehind = gitService.getAheadBehind(name);
if (aheadBehind != null)
{
model.addAttribute("commitsAhead", aheadBehind[0]);
model.addAttribute("commitsBehind", aheadBehind[1]);
}
return "changes";
}
@@ -224,17 +230,19 @@ public class RepoController
}
@PostMapping("/repo/{name}/push")
public String push(@PathVariable String name) throws IOException, GitAPIException
public String push(@PathVariable String name,
@RequestParam(required = false, defaultValue = "remote") String redirectTo) throws IOException, GitAPIException
{
gitService.push(name);
return "redirect:/repo/" + name + "/remote";
return "redirect:/repo/" + name + "/" + redirectTo;
}
@PostMapping("/repo/{name}/pull")
public String pull(@PathVariable String name) throws IOException, GitAPIException
public String pull(@PathVariable String name,
@RequestParam(required = false, defaultValue = "remote") String redirectTo) throws IOException, GitAPIException
{
gitService.pull(name);
return "redirect:/repo/" + name + "/remote";
return "redirect:/repo/" + name + "/" + redirectTo;
}
@PostMapping("/repo/{name}/update-remote")

View File

@@ -598,11 +598,28 @@ public class GitService
}
}
public int[] getAheadBehind(String name) throws IOException
{
try (Git git = openRepository(name))
{
String branch = git.getRepository().getBranch();
org.eclipse.jgit.lib.BranchTrackingStatus status =
org.eclipse.jgit.lib.BranchTrackingStatus.of(git.getRepository(), branch);
if (status == null)
return null;
return new int[]{status.getAheadCount(), status.getBehindCount()};
}
}
public void push(String name) throws IOException, GitAPIException
{
try (Git git = openRepository(name))
{
git.push().call();
var cmd = git.push();
if (properties.getUsername() != null)
cmd.setCredentialsProvider(new org.eclipse.jgit.transport.UsernamePasswordCredentialsProvider(
properties.getUsername(), properties.getPassword()));
cmd.call();
}
}
@@ -610,7 +627,11 @@ public class GitService
{
try (Git git = openRepository(name))
{
git.pull().call();
var cmd = git.pull();
if (properties.getUsername() != null)
cmd.setCredentialsProvider(new org.eclipse.jgit.transport.UsernamePasswordCredentialsProvider(
properties.getUsername(), properties.getPassword()));
cmd.call();
}
}

View File

@@ -4,3 +4,7 @@ webgit.worktree-path=./webgit/worktree
webgit.telnet.enabled=true
webgit.telnet-port=2323
# Optional: credentials for push/pull (can also be set via WEBGIT_USERNAME / WEBGIT_PASSWORD env vars)
#webgit.username=
#webgit.password=

View File

@@ -6,6 +6,17 @@
<body>
<h2>Staging</h2>
<p>Branch: <b th:text="${branch}"></b></p>
<p th:if="${commitsAhead != null}">
<span th:text="${commitsAhead}"></span> ahead, <span th:text="${commitsBehind}"></span> behind
<form method="post" th:action="@{/repo/{name}/push(name=${name})}">
<input type="hidden" name="redirectTo" value="changes">
<input type="submit" value="Push">
</form>
<form method="post" th:action="@{/repo/{name}/pull(name=${name})}">
<input type="hidden" name="redirectTo" value="changes">
<input type="submit" value="Pull">
</form>
</p>
<h3>Modified Files (unstaged)</h3>
<form method="post" th:action="@{/repo/{name}/stage(name=${name})}" th:if="${!#lists.isEmpty(modifiedFiles)}">