Skip to content

Commit 08e2bbb

Browse files
authored
Handle detached HEAD and initial commit (#25)
* Handle detached head and initial commit * Add end-to-end test for detached head * Update comments in the main file
1 parent ec39018 commit 08e2bbb

File tree

3 files changed

+77
-28
lines changed

3 files changed

+77
-28
lines changed

cmd/commit/main.go

Lines changed: 24 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"fmt"
66
"os"
77
"path/filepath"
8+
"strings"
89
"time"
910

1011
"github.com/artem-y/commit/internal/config"
@@ -13,7 +14,6 @@ import (
1314
"github.com/artem-y/commit/internal/user"
1415

1516
"github.com/go-git/go-git/v5"
16-
"github.com/go-git/go-git/v5/plumbing"
1717
"github.com/go-git/go-git/v5/plumbing/object"
1818
)
1919

@@ -47,36 +47,44 @@ func main() {
4747
)
4848
}
4949

50-
headRef := getCurrentHead(repo)
50+
headFilePath := filepath.Join(
51+
worktree.Filesystem.Root(),
52+
".git",
53+
"HEAD",
54+
)
55+
56+
fileReader := config.FileReader{}
5157

52-
// Read branch name or HEAD
53-
if headRef.Name().IsBranch() {
58+
// Read current HEAD from file
59+
headFile, _ := fileReader.ReadFile(headFilePath)
60+
headFileText := string(headFile)
61+
62+
// If there is a branch name in the HEAD file, modify the commit message
63+
if strings.HasPrefix(headFileText, helpers.HEAD_REF_PREFIX) {
64+
branchName := strings.TrimPrefix(
65+
headFileText,
66+
helpers.HEAD_REF_PREFIX,
67+
)
5468

55-
fileReader := config.FileReader{}
5669
cfg, err := config.ReadCommitConfig(fileReader, configFilePath)
5770
if err != nil {
5871
fmt.Fprintf(os.Stderr, helpers.Red("Failed to read config: %v\n"), err)
5972
os.Exit(1)
6073
}
6174

6275
messageGenerator := message_generator.MessageGenerator{
63-
BranchName: headRef.Name().Short(),
76+
BranchName: branchName,
6477
UserMessage: commitMessage,
6578
Config: cfg,
6679
}
6780
commitMessage = messageGenerator.GenerateMessage()
81+
}
6882

69-
if !dryRun {
70-
commitChanges(repo, worktree, commitMessage)
71-
}
72-
73-
fmt.Println(commitMessage)
74-
75-
} else if headRef.Name().IsTag() {
76-
fmt.Printf("HEAD is a tag: %v\n", headRef.Name().Short())
77-
} else {
78-
fmt.Printf("Detached HEAD at %v\n", headRef.Hash())
83+
if !dryRun {
84+
commitChanges(repo, worktree, commitMessage)
7985
}
86+
87+
fmt.Println(commitMessage)
8088
}
8189

8290
// Reads commit message from command line arguments
@@ -104,16 +112,6 @@ func openRepo() *git.Repository {
104112
return repo
105113
}
106114

107-
// Reads the current HEAD reference
108-
func getCurrentHead(repo *git.Repository) *plumbing.Reference {
109-
headRef, err := repo.Head()
110-
if err != nil {
111-
fmt.Fprintf(os.Stderr, helpers.Red("Failed to read current HEAD: %v\n"), err)
112-
os.Exit(1)
113-
}
114-
return headRef
115-
}
116-
117115
// Opens worktree
118116
func openWorktree(repo *git.Repository) *git.Worktree {
119117
worktree, err := repo.Worktree()

e2e.sh

Lines changed: 52 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,7 @@ setup_test_repository() {
3232
git init && \
3333
# Set up local git config inside the new directory
3434
git config --local user.name "GitHub Actions CI Runner" && \
35-
git config --local user.email "--" && \
36-
touch file && git add file && git commit -m "Initial commit"
35+
git config --local user.email "--"
3736
}
3837

3938
start_test() {
@@ -251,6 +250,56 @@ test_use_config_with_empty_regex() {
251250

252251
}
253252

253+
test_commit_with_detached_head() {
254+
TESTNAME="test_commit_with_detached_head"
255+
start_test $TESTNAME
256+
257+
setup_test_repository &&\
258+
git config --local advice.detachedHead false && \
259+
git checkout -b feature/DEV-21-validation && \
260+
261+
# Write a config file
262+
echo '
263+
{
264+
"issueRegex": "DEV-[0-9]+",
265+
"outputIssuePrefix": "",
266+
"outputIssueSuffix": "",
267+
"outputStringPrefix": "[",
268+
"outputStringSuffix": "] "
269+
}
270+
' > .commit.json && \
271+
272+
# Create the initial commit
273+
echo "Hello, World!" > hello1 && \
274+
git add hello1 && \
275+
../bin/commit "Initial commit" && \
276+
277+
# Create the second commit
278+
touch hello2 && \
279+
git add hello2 && \
280+
../bin/commit "Second commit" && \
281+
282+
# Checkout the previous commit
283+
git checkout 'HEAD^' && \
284+
285+
# Create commit with alternative changes
286+
touch hello3 && \
287+
git add hello3 && \
288+
../bin/commit "Alternative commit"
289+
290+
# Check if the commit was successful
291+
if [ $? -ne 0 ]; then
292+
fail_test $TESTNAME
293+
fi
294+
295+
# Check if the commit message is correct
296+
if [ "$(git log -1 --pretty=%B)" != 'Alternative commit' ]; then
297+
fail_test $TESTNAME
298+
fi
299+
300+
pass_test $TESTNAME
301+
}
302+
254303
# MARK: - Run Tests
255304

256305
build_if_needed
@@ -260,3 +309,4 @@ test_use_config_from_current_directory
260309
test_commit_from_subdirectory
261310
test_set_correct_author
262311
test_use_config_with_empty_regex
312+
test_commit_with_detached_head

internal/helpers/constants.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,5 @@ const (
77
DEFAULT_OUTPUT_ISSUE_SUFFIX = ""
88
DEFAULT_OUTPUT_STRING_PREFIX = ""
99
DEFAULT_OUTPUT_STRING_SUFFIX = ": "
10+
HEAD_REF_PREFIX = "ref: refs/heads/"
1011
)

0 commit comments

Comments
 (0)