-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcmd_commit.go
More file actions
105 lines (81 loc) · 2.88 KB
/
cmd_commit.go
File metadata and controls
105 lines (81 loc) · 2.88 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
package main
import (
"context"
"fmt"
"os"
"strings"
)
type CommitCmd struct {
remoteFlags
Author string `help:"Specify an author using the standard 'A U Thor <author@example.com>' format."`
Message []string `short:"m" help:"Specify a commit message. If used multiple times, values are concatenated as separate paragraphs."`
}
func (c *CommitCmd) Help() string {
return `
This command creates a single commit on the remote from the currently staged changes (git add).
It works like 'git commit' - stage your changes first, then run this command to push them as a
signed commit on the remote.
The staged file paths must match the paths on the remote. That is, if you stage "path/to/file.txt"
then the contents of that file will be applied to that same path on the remote.
Staged deletions (git rm) are also supported.
You can supply a commit message via --message/-m and an author via --author. If unspecified,
default values will be used.
Unlike 'push', this command does not require any relationship between local and remote history.
This makes it useful for broadcasting the same file changes to multiple repositories:
git add config.yml security-policy.md
commit-headless commit -T org/repo1 --branch main -m "Update security policy"
commit-headless commit -T org/repo2 --branch main -m "Update security policy"
commit-headless commit -T org/repo3 --branch main -m "Update security policy"
Each target repository can have completely unrelated history - you're applying file contents,
not replaying commits.
Examples:
# Stage changes and commit to remote
git add README.md .gitlab-ci.yml
commit-headless commit -T owner/repo --branch feature -m "Update docs"
# Stage a deletion and a new file
git rm old-file.txt
git add new-file.txt
commit-headless commit -T owner/repo --branch feature -m "Replace old with new"
# Stage all changes and commit
git add -A
commit-headless commit -T owner/repo --branch feature -m "Update everything"
`
}
func (c *CommitCmd) Run() error {
repo := &Repository{path: c.RepoPath}
entries, err := repo.StagedChanges()
if err != nil {
return err
}
if len(entries) == 0 {
logger.Notice("No staged changes to commit")
return nil
}
change := Change{
hash: strings.Repeat("0", 40),
author: c.Author,
message: strings.Join(c.Message, "\n\n"),
entries: entries,
}
ctx := context.Background()
token := getToken(os.Getenv)
if token == "" {
return fmt.Errorf("no GitHub token supplied")
}
client := NewClient(ctx, token, c.Target.Owner(), c.Target.Repository(), c.Branch)
client.dryrun = c.DryRun
client.force = c.Force
client.signAttempts = c.SignAttempts
baseCommit, err := c.ResolveBaseCommit(ctx, client)
if err != nil {
return err
}
if c.CreateBranch {
remoteSha, err := client.CreateBranch(ctx, baseCommit)
if err != nil {
return err
}
baseCommit = remoteSha
}
return pushChanges(ctx, client, baseCommit, change)
}