Skip to content

Commit a9ebe49

Browse files
authored
Show all changes from branch point on feature branches (#14)
1 parent a4c9288 commit a9ebe49

File tree

2 files changed

+183
-1
lines changed

2 files changed

+183
-1
lines changed

handlers.go

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,27 @@ func serveDiffsText(w http.ResponseWriter, r *http.Request) {
8282
}
8383

8484
cmd := exec.CommandContext(ctx, "bash", "-c", `
85-
git diff --src-prefix=a/`+repoName+`/ --dst-prefix=b/`+repoName+`/ HEAD
85+
# Determine the default branch (main or master)
86+
DEFAULT_BRANCH=""
87+
if git rev-parse --verify main >/dev/null 2>&1; then
88+
DEFAULT_BRANCH="main"
89+
elif git rev-parse --verify master >/dev/null 2>&1; then
90+
DEFAULT_BRANCH="master"
91+
fi
92+
93+
# Get current branch
94+
CURRENT_BRANCH=$(git symbolic-ref --short HEAD 2>/dev/null || echo "")
95+
96+
# Determine what to diff against
97+
if [ -n "$DEFAULT_BRANCH" ] && [ -n "$CURRENT_BRANCH" ] && [ "$CURRENT_BRANCH" != "$DEFAULT_BRANCH" ]; then
98+
# On a feature branch: show all changes from branch point
99+
git diff --src-prefix=a/`+repoName+`/ --dst-prefix=b/`+repoName+`/ ${DEFAULT_BRANCH}...HEAD
100+
else
101+
# On default branch or detached HEAD: show only uncommitted changes
102+
git diff --src-prefix=a/`+repoName+`/ --dst-prefix=b/`+repoName+`/ HEAD
103+
fi
104+
105+
# Always show untracked files
86106
git ls-files --others --exclude-standard | while IFS= read -r file; do
87107
if [ -n "$file" ]; then
88108
git diff --no-index --src-prefix=a/`+repoName+`/ --dst-prefix=b/`+repoName+`/ /dev/null "$file" 2>/dev/null || true

handlers_test.go

Lines changed: 162 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -283,3 +283,165 @@ func TestServeDiffsText_NonGitDirectory(t *testing.T) {
283283
// Should return empty response since there are no git repos
284284
// This tests that the handler completes successfully even with no repos
285285
}
286+
287+
func TestServeDiffsText_FeatureBranchShowsAllChanges(t *testing.T) {
288+
tmpDir := t.TempDir()
289+
290+
setupTestGitRepo(t, tmpDir)
291+
292+
// Create initial commit on master
293+
testFile := filepath.Join(tmpDir, "initial.txt")
294+
if err := os.WriteFile(testFile, []byte("initial\n"), 0644); err != nil {
295+
t.Fatalf("failed to write test file: %v", err)
296+
}
297+
298+
cmd := exec.Command("git", "add", "initial.txt")
299+
cmd.Dir = tmpDir
300+
if err := cmd.Run(); err != nil {
301+
t.Fatalf("failed to git add: %v", err)
302+
}
303+
304+
cmd = exec.Command("git", "commit", "-m", "initial commit")
305+
cmd.Dir = tmpDir
306+
if err := cmd.Run(); err != nil {
307+
t.Fatalf("failed to commit: %v", err)
308+
}
309+
310+
// Create feature branch
311+
cmd = exec.Command("git", "checkout", "-b", "feature")
312+
cmd.Dir = tmpDir
313+
if err := cmd.Run(); err != nil {
314+
t.Fatalf("failed to create feature branch: %v", err)
315+
}
316+
317+
// Add committed change on feature branch
318+
committedFile := filepath.Join(tmpDir, "committed.txt")
319+
if err := os.WriteFile(committedFile, []byte("committed on feature\n"), 0644); err != nil {
320+
t.Fatalf("failed to write committed file: %v", err)
321+
}
322+
323+
cmd = exec.Command("git", "add", "committed.txt")
324+
cmd.Dir = tmpDir
325+
if err := cmd.Run(); err != nil {
326+
t.Fatalf("failed to git add: %v", err)
327+
}
328+
329+
cmd = exec.Command("git", "commit", "-m", "committed change on feature")
330+
cmd.Dir = tmpDir
331+
if err := cmd.Run(); err != nil {
332+
t.Fatalf("failed to commit: %v", err)
333+
}
334+
335+
// Add uncommitted change on feature branch
336+
uncommittedFile := filepath.Join(tmpDir, "uncommitted.txt")
337+
if err := os.WriteFile(uncommittedFile, []byte("uncommitted on feature\n"), 0644); err != nil {
338+
t.Fatalf("failed to write uncommitted file: %v", err)
339+
}
340+
341+
oldDir, _ := os.Getwd()
342+
defer os.Chdir(oldDir)
343+
344+
if err := os.Chdir(tmpDir); err != nil {
345+
t.Fatalf("failed to chdir: %v", err)
346+
}
347+
348+
req := httptest.NewRequest("GET", "/", nil)
349+
req.Header.Set("Accept", "text/x-diff")
350+
351+
w := httptest.NewRecorder()
352+
diffsHandler(w, req)
353+
354+
resp := w.Result()
355+
if resp.StatusCode != http.StatusOK {
356+
t.Errorf("expected status 200, got %d", resp.StatusCode)
357+
}
358+
359+
body := w.Body.String()
360+
361+
// Should show both committed and uncommitted changes
362+
if !strings.Contains(body, "committed.txt") {
363+
t.Errorf("expected committed.txt in diff (committed change from branch), got: %s", body)
364+
}
365+
if !strings.Contains(body, "uncommitted.txt") {
366+
t.Errorf("expected uncommitted.txt in diff (uncommitted change), got: %s", body)
367+
}
368+
}
369+
370+
func TestServeDiffsText_MasterBranchShowsOnlyUncommitted(t *testing.T) {
371+
tmpDir := t.TempDir()
372+
373+
setupTestGitRepo(t, tmpDir)
374+
375+
// Create initial commit on master
376+
testFile := filepath.Join(tmpDir, "initial.txt")
377+
if err := os.WriteFile(testFile, []byte("initial\n"), 0644); err != nil {
378+
t.Fatalf("failed to write test file: %v", err)
379+
}
380+
381+
cmd := exec.Command("git", "add", "initial.txt")
382+
cmd.Dir = tmpDir
383+
if err := cmd.Run(); err != nil {
384+
t.Fatalf("failed to git add: %v", err)
385+
}
386+
387+
cmd = exec.Command("git", "commit", "-m", "initial commit")
388+
cmd.Dir = tmpDir
389+
if err := cmd.Run(); err != nil {
390+
t.Fatalf("failed to commit: %v", err)
391+
}
392+
393+
// Add another committed change on master
394+
committedFile := filepath.Join(tmpDir, "committed.txt")
395+
if err := os.WriteFile(committedFile, []byte("committed on master\n"), 0644); err != nil {
396+
t.Fatalf("failed to write committed file: %v", err)
397+
}
398+
399+
cmd = exec.Command("git", "add", "committed.txt")
400+
cmd.Dir = tmpDir
401+
if err := cmd.Run(); err != nil {
402+
t.Fatalf("failed to git add: %v", err)
403+
}
404+
405+
cmd = exec.Command("git", "commit", "-m", "committed change on master")
406+
cmd.Dir = tmpDir
407+
if err := cmd.Run(); err != nil {
408+
t.Fatalf("failed to commit: %v", err)
409+
}
410+
411+
// Add uncommitted change on master
412+
uncommittedFile := filepath.Join(tmpDir, "uncommitted.txt")
413+
if err := os.WriteFile(uncommittedFile, []byte("uncommitted on master\n"), 0644); err != nil {
414+
t.Fatalf("failed to write uncommitted file: %v", err)
415+
}
416+
417+
oldDir, _ := os.Getwd()
418+
defer os.Chdir(oldDir)
419+
420+
if err := os.Chdir(tmpDir); err != nil {
421+
t.Fatalf("failed to chdir: %v", err)
422+
}
423+
424+
req := httptest.NewRequest("GET", "/", nil)
425+
req.Header.Set("Accept", "text/x-diff")
426+
427+
w := httptest.NewRecorder()
428+
diffsHandler(w, req)
429+
430+
resp := w.Result()
431+
if resp.StatusCode != http.StatusOK {
432+
t.Errorf("expected status 200, got %d", resp.StatusCode)
433+
}
434+
435+
body := w.Body.String()
436+
437+
// Should NOT show committed changes (committed.txt was committed, so should not appear in diff)
438+
// Look for "a/./committed.txt" or "b/./committed.txt" in diff headers
439+
if strings.Contains(body, "a/./committed.txt") || strings.Contains(body, "b/./committed.txt") {
440+
t.Errorf("should not show committed.txt changes on master branch since it was already committed, got: %s", body)
441+
}
442+
// Should show uncommitted changes
443+
if !strings.Contains(body, "uncommitted.txt") {
444+
t.Errorf("expected uncommitted.txt in diff (uncommitted change), got: %s", body)
445+
}
446+
}
447+

0 commit comments

Comments
 (0)