Rename trunk branch to main branch

message: |-
  Rename trunk branch to main branch

  The term "trunk" is too close to "branch", imo, and is confusing since its
  inverse term, "thread", isn't related to branch at all. Ultimately I think it's
  best to leave "branch" as a git specific term, and use "main" and "thread" to
  denote the different branch types of dehub.
change_hash: ANitkSWx+QHnxo/d0zg+lrWdeqx1PHqH2GQ2uvyMYZNa
credentials:
- type: pgp_signature
  pub_key_id: 95C46FA6A41148AC
  body: iQIyBAABAgAdFiEEJ6tQKp6olvZKJ0lwlcRvpqQRSKwFAl5f/ikACgkQlcRvpqQRSKw04Q/4sX9Ylt8vdkhnT24vRqf7uoO2WsRCs4uHvr3tW5V735o3ReKE4KWT9crIKSSn92vkEaFdNAr8+9M7CMfa3qKLAd0kVbGIDiZ775+4jw/Px+nyORSkl17F5gji3m3kM6rnvqYtg5r1NvxuIeuqNK8TGojtlAsf1hN6inrB6S7MEAgw/wYRMQjV7ohYFkeMMLzaN+Q1YA4LolfnM4JbsIwcFMHC1jxDe6is22lUxR1XqTEzJqpIQLLCtY4Ds6LECqm0cFRlXic1ldcYqHxZvWLks8MdNtkMq0FqwEUtr07IqWUAyWcMsmKkReSbTfqPlizJOZ9J4c+8p5FIkRNl+TuJnfB4oBNANMmEHeeHNY3a5pfeJFOyfzAq7LfOwYBMfWcNvX4kuKfAKhSI55Snb6vK4ChRget3VruOZaFIjfAxWQX5QVcDufh3EJvuCJ1lJKKxdqIHQO95hvJ4cMgz1+pxPnQabEkFlk0Q+qFYS4u1S89y5lWxc5GIRaZX6X43/r74rB027LN9eqsovrJ0MLFHRH3QagS9YxDUsVWnv1Y/8TvUn65QRIsHbmrF1ESYdjycROh1bhTJLwwqrSwQjm5HhquvJ93DzUNgRZDLRXwDGL2raJ7oeNL+6E2fl8ahPntmvdVFWtXsMNK93/IKkW3brxUoBkWt5rzKqE4TRhWjDw==
  account: mediocregopher
This commit is contained in:
mediocregopher 2020-03-04 12:14:54 -07:00
parent 1db3f2bd1e
commit 981fbb8327
11 changed files with 49 additions and 53 deletions

View File

@ -46,14 +46,14 @@ platforms like IPFS.
### Example ### Example
MyProject wants to ensure that at least 2 of the 3 maintainers sign off on a MyProject wants to ensure that at least 2 of the 3 maintainers sign off on a
commit before the commit can be placed into the `trunk` branch (dehub's commit before the commit can be placed into the `main` branch (dehub's
equivalent of the `master` branch). MyProject's repo would contain a equivalent of the `master` branch). MyProject's repo would contain a
`.dehub/config.yml` file with the following access controls set: `.dehub/config.yml` file with the following access controls set:
``` ```
# ... # ...
access_controls: access_controls:
- branch_pattern: trunk - branch_pattern: main
change_access_controls: change_access_controls:
# matches all files, but could be used for more fine-grained control # matches all files, but could be used for more fine-grained control
- file_path_pattern: "**" - file_path_pattern: "**"
@ -66,7 +66,7 @@ access_controls:
count: 2 count: 2
``` ```
A commit in the `trunk` branch would have a message with the following form: A commit in the `main` branch would have a message with the following form:
``` ```
This is the first line of the commit message. It remains human readable This is the first line of the commit message. It remains human readable
@ -98,14 +98,14 @@ credentials:
``` ```
The `credentials` contains signatures of both the commit message and its The `credentials` contains signatures of both the commit message and its
changes, allowing it to be added to the `trunk`. A simple git hook is all that's changes, allowing it to be added to the `main`. A simple git hook is all that's
needed to verify commits in `trunk` when they are pushed or pulled. needed to verify commits in `main` when they are pushed or pulled.
## dehub Thread Branches ## dehub Thread Branches
The `trunk` branch is the project's source-of-truth. Other branches, called The `main` branch is the project's source-of-truth. Other branches, called
threads, are used to coordinate new changes, and then coalesce those changes threads, are used to coordinate new changes, and then coalesce those changes
into a commit suitable for `trunk`. into a commit suitable for `main`.
### Example ### Example
@ -126,7 +126,7 @@ credentials:
account: alice account: alice
# Note that this commit does not have enough credentials to be allowed in the # Note that this commit does not have enough credentials to be allowed in the
# trunk branch. # main branch.
``` ```
Bob sees the new thread branch and looks through it. He pushes the following Bob sees the new thread branch and looks through it. He pushes the following
@ -174,7 +174,7 @@ credentials:
account: alice account: alice
# Note that this commit does not have enough credentials to be allowed in the # Note that this commit does not have enough credentials to be allowed in the
# trunk branch. # main branch.
``` ```
Bob, happy with these changes, pushes a commit to the thread which adds his own Bob, happy with these changes, pushes a commit to the thread which adds his own
@ -199,23 +199,23 @@ can do once all the required credentials are available.
To coalesce, the following is done: All file changes in the branch are squashed To coalesce, the following is done: All file changes in the branch are squashed
into a single change commit, using the latest commit message which was pushed by Alice. into a single change commit, using the latest commit message which was pushed by Alice.
Bob's signature is added to the change commit message as a credential. The Bob's signature is added to the change commit message as a credential. The
commit can then be pushed to `trunk` (because it now has two credentials) and commit can then be pushed to `main` (because it now has two credentials) and
`featureBranch` can be deleted. `featureBranch` can be deleted.
## Pre-emptively Answered Questions ## Pre-emptively Answered Questions
**How can I trust that the git history I've received is legitimate?** **How can I trust that the git history I've received is legitimate?**
Each commit in `trunk` can have its credentials verified locally. Credentials Each commit in `main` can have its credentials verified locally. Credentials
are currently provided by pgp signatures, so your trust in the git chain can be are currently provided by pgp signatures, so your trust in the git chain can be
as strong as your trust in those signatures. Support for other kinds of as strong as your trust in those signatures. Support for other kinds of
credentials (e.g. keybase signatures) will increase the number of options for credentials (e.g. keybase signatures) will increase the number of options for
trust the user has. trust the user has.
**Why `trunk`?** **Why `main`?**
The primary branch in most git projects is called `master`. It makes sense to The primary branch in most git projects is called `master`. It makes sense to
use a different one, `trunk`, for dehub, since the commits on it will be use a different one, `main`, for dehub, since the commits on it will be
following a specific protocol which is not compatible with most `master` following a specific protocol which is not compatible with most `master`
branches. By having a different primary branch convention we can prevent undue branches. By having a different primary branch convention we can prevent undue
conflict, as well as make it easy to tell at a glance what kind of project is conflict, as well as make it easy to tell at a glance what kind of project is

View File

@ -20,10 +20,6 @@ set, only a sequence of milestones and the requirements to hit them.
## Milestone: Enough polish to show off the project ## Milestone: Enough polish to show off the project
* Possibly rename "trunk", it's kind of weird as being a kind of branch,
especially when its corallary type is "thread" which has nothing to do with
trees.
* Polish commands * Polish commands
- New flag system, some kind of interactivity support (e.g. user doesn't - New flag system, some kind of interactivity support (e.g. user doesn't
specify required argument, give them a prompt on the CLI to input it specify required argument, give them a prompt on the CLI to input it

14
SPEC.md
View File

@ -35,7 +35,7 @@ access_controls:
# branch_pattern is a glob pattern describing what branch names this access # branch_pattern is a glob pattern describing what branch names this access
# control applies to. The first matching branch_pattern for a branch name # control applies to. The first matching branch_pattern for a branch name
# defines which access controls are applied. # defines which access controls are applied.
- branch_pattern: trunk - branch_pattern: main
# change_access_controls is an array of possible access controls applied for # change_access_controls is an array of possible access controls applied for
# files being changed in the branch # files being changed in the branch
@ -113,7 +113,7 @@ compatibility). The result is the raw change hash.
# Credentials # Credentials
All file changes need to have some kind of credential to be accepted into the All file changes need to have some kind of credential to be accepted into the
`trunk` branch (see Trunk Branch section). Each credential is encoded as a yaml `main` branch (see Main Branch section). Each credential is encoded as a yaml
object with a `type` field. object with a `type` field.
All credentials contain enough information to correspond them to a specific All credentials contain enough information to correspond them to a specific
@ -218,10 +218,10 @@ dehub branches correspond 1-to-1 with branches in the underlying git repo. All
commits in a dehub branch should contain an encoded message as specified in the commits in a dehub branch should contain an encoded message as specified in the
Commits section of this document, and possibly file changes as appropriate. Commits section of this document, and possibly file changes as appropriate.
## Trunk Branch ## Main Branch
The "primary" branch of a dehub repo is the `trunk` branch. All new commits The "primary" branch of a dehub repo is the `main` branch. All new commits
being appended to the HEAD of the `trunk` branch are subject to the following being appended to the HEAD of the `main` branch are subject to the following
requirements: requirements:
* Must be `change` commits. * Must be `change` commits.
@ -236,8 +236,8 @@ requirements:
## Thread Branches ## Thread Branches
Branches which are not the `trunk` branch are referred to as "threads", and have Branches which are not the `main` branch are referred to as "threads", and have
much less stringent requirements than the `trunk` branch: much less stringent requirements than the `main` branch:
* They can contain commits of any type, as long as the commits come from those * They can contain commits of any type, as long as the commits come from those
with an account defined in the `config.yml`. with an account defined in the `config.yml`.

View File

@ -28,7 +28,7 @@ var (
// These are currently the same, but they will differ once things like // These are currently the same, but they will differ once things like
// comments start being implemented. // comments start being implemented.
{ {
BranchPattern: "trunk", BranchPattern: "main",
ChangeAccessControls: []ChangeAccessControl{DefaultChangeAccessControl}, ChangeAccessControls: []ChangeAccessControl{DefaultChangeAccessControl},
}, },
{ {

View File

@ -38,11 +38,11 @@ func TestMatch(t *testing.T) {
{ {
descr: "empty access controls", descr: "empty access controls",
interactions: MatchInteractions{ interactions: MatchInteractions{
Branch: "trunk", Branch: "main",
FilePathsChanged: []string{"foo", "bar"}, FilePathsChanged: []string{"foo", "bar"},
}, },
result: MatchResult{ result: MatchResult{
BranchPattern: "trunk", BranchPattern: "main",
ChangeAccessControls: []MatchedChangeAccessControl{ ChangeAccessControls: []MatchedChangeAccessControl{
{ {
ChangeAccessControl: DefaultChangeAccessControl, ChangeAccessControl: DefaultChangeAccessControl,
@ -54,8 +54,8 @@ func TestMatch(t *testing.T) {
{ {
descr: "empty filesPathsChanged", descr: "empty filesPathsChanged",
branchACs: DefaultBranchAccessControls, branchACs: DefaultBranchAccessControls,
interactions: MatchInteractions{Branch: "trunk"}, interactions: MatchInteractions{Branch: "main"},
result: MatchResult{BranchPattern: "trunk"}, result: MatchResult{BranchPattern: "main"},
}, },
{ {
descr: "no matching branch patterns", descr: "no matching branch patterns",
@ -81,18 +81,18 @@ func TestMatch(t *testing.T) {
{ {
descr: "no matching files", descr: "no matching files",
branchACs: []BranchAccessControl{{ branchACs: []BranchAccessControl{{
BranchPattern: "trunk", BranchPattern: "main",
ChangeAccessControls: []ChangeAccessControl{{ ChangeAccessControls: []ChangeAccessControl{{
FilePathPattern: "boo", FilePathPattern: "boo",
Condition: secondCond, Condition: secondCond,
}}, }},
}}, }},
interactions: MatchInteractions{ interactions: MatchInteractions{
Branch: "trunk", Branch: "main",
FilePathsChanged: []string{"foo"}, FilePathsChanged: []string{"foo"},
}, },
result: MatchResult{ result: MatchResult{
BranchPattern: "trunk", BranchPattern: "main",
ChangeAccessControls: []MatchedChangeAccessControl{{ ChangeAccessControls: []MatchedChangeAccessControl{{
ChangeAccessControl: DefaultChangeAccessControl, ChangeAccessControl: DefaultChangeAccessControl,
FilePaths: []string{"foo"}, FilePaths: []string{"foo"},
@ -103,7 +103,7 @@ func TestMatch(t *testing.T) {
descr: "branch pattern precedent", descr: "branch pattern precedent",
branchACs: []BranchAccessControl{ branchACs: []BranchAccessControl{
{ {
BranchPattern: "trunk", BranchPattern: "main",
ChangeAccessControls: []ChangeAccessControl{{ ChangeAccessControls: []ChangeAccessControl{{
FilePathPattern: "foo", FilePathPattern: "foo",
Condition: secondCond, Condition: secondCond,
@ -117,11 +117,11 @@ func TestMatch(t *testing.T) {
}, },
}, },
interactions: MatchInteractions{ interactions: MatchInteractions{
Branch: "trunk", Branch: "main",
FilePathsChanged: []string{"foo"}, FilePathsChanged: []string{"foo"},
}, },
result: MatchResult{ result: MatchResult{
BranchPattern: "trunk", BranchPattern: "main",
ChangeAccessControls: []MatchedChangeAccessControl{{ ChangeAccessControls: []MatchedChangeAccessControl{{
ChangeAccessControl: ChangeAccessControl{ ChangeAccessControl: ChangeAccessControl{
FilePathPattern: "foo", FilePathPattern: "foo",
@ -134,18 +134,18 @@ func TestMatch(t *testing.T) {
{ {
descr: "multiple files matching FilePathPatterns", descr: "multiple files matching FilePathPatterns",
branchACs: []BranchAccessControl{{ branchACs: []BranchAccessControl{{
BranchPattern: "trunk", BranchPattern: "main",
ChangeAccessControls: []ChangeAccessControl{{ ChangeAccessControls: []ChangeAccessControl{{
FilePathPattern: "foo*", FilePathPattern: "foo*",
Condition: secondCond, Condition: secondCond,
}}, }},
}}, }},
interactions: MatchInteractions{ interactions: MatchInteractions{
Branch: "trunk", Branch: "main",
FilePathsChanged: []string{"foo_a", "bar", "foo_b"}, FilePathsChanged: []string{"foo_a", "bar", "foo_b"},
}, },
result: MatchResult{ result: MatchResult{
BranchPattern: "trunk", BranchPattern: "main",
ChangeAccessControls: []MatchedChangeAccessControl{ ChangeAccessControls: []MatchedChangeAccessControl{
{ {
ChangeAccessControl: DefaultChangeAccessControl, ChangeAccessControl: DefaultChangeAccessControl,

View File

@ -2,7 +2,7 @@
This directory provides a simple Docker image which can be spun up to run a This directory provides a simple Docker image which can be spun up to run a
dehub-enabled git http server (i.e. one in which incoming commits will be dehub-enabled git http server (i.e. one in which incoming commits will be
verified prior to being accepted into the `trunk` branch). verified prior to being accepted into the `main` branch).
The docker image is also being hosted on docker hub at `mediocregopher/dehub`. The docker image is also being hosted on docker hub at `mediocregopher/dehub`.
Proper image tagging/versioning coming soon! Proper image tagging/versioning coming soon!

View File

@ -74,7 +74,7 @@ while [ ! -z "$1" ]; do
git init --bare "$dir" git init --bare "$dir"
git config -f "$dir/config" http.receivepack true git config -f "$dir/config" http.receivepack true
git config -f "$dir/config" receive.denyNonFastForwards true git config -f "$dir/config" receive.denyNonFastForwards true
git symbolic-ref HEAD refs/heads/trunk git symbolic-ref HEAD refs/heads/main
chown -R git:git "$dir" chown -R git:git "$dir"
fi fi

View File

@ -81,7 +81,7 @@ func TestChangeCommitVerify(t *testing.T) {
account := h.cfg.Accounts[0] account := h.cfg.Accounts[0]
changeCommit, hash := h.changeCommit(step.msg, account.ID, h.sig) changeCommit, hash := h.changeCommit(step.msg, account.ID, h.sig)
if err := h.repo.VerifyChangeCommit(TrunkRefName, hash); err != nil { if err := h.repo.VerifyChangeCommit(MainRefName, hash); err != nil {
t.Fatalf("could not verify hash %v: %v", hash, err) t.Fatalf("could not verify hash %v: %v", hash, err)
} }
@ -137,7 +137,7 @@ func TestConfigChange(t *testing.T) {
h.stage(map[string]string{ConfigPath: string(cfgBody)}) h.stage(map[string]string{ConfigPath: string(cfgBody)})
_, badHash := h.changeCommit("add toot user", h.cfg.Accounts[1].ID, newSig) _, badHash := h.changeCommit("add toot user", h.cfg.Accounts[1].ID, newSig)
if err := h.repo.VerifyChangeCommit(TrunkRefName, badHash); err == nil { if err := h.repo.VerifyChangeCommit(MainRefName, badHash); err == nil {
t.Fatal("toot user shouldn't be able to add itself to config") t.Fatal("toot user shouldn't be able to add itself to config")
} }
h.reset(hash, git.HardReset) h.reset(hash, git.HardReset)
@ -153,7 +153,7 @@ func TestConfigChange(t *testing.T) {
hashes = append(hashes, hash) hashes = append(hashes, hash)
for i, hash := range hashes { for i, hash := range hashes {
if err := h.repo.VerifyChangeCommit(TrunkRefName, hash); err != nil { if err := h.repo.VerifyChangeCommit(MainRefName, hash); err != nil {
t.Fatalf("commit %d (%v) should have been verified but wasn't: %v", i, hash, err) t.Fatalf("commit %d (%v) should have been verified but wasn't: %v", i, hash, err)
} }
} }

12
repo.go
View File

@ -26,11 +26,11 @@ var (
// ConfigPath defines the expected path to the Repo's configuration file. // ConfigPath defines the expected path to the Repo's configuration file.
ConfigPath = filepath.Join(DehubDir, "config.yml") ConfigPath = filepath.Join(DehubDir, "config.yml")
// Trunk defines the name of the trunk branch. // Main defines the name of the main branch.
Trunk = "trunk" Main = "main"
// TrunkRefName defines the reference name of the trunk branch. // MainRefName defines the reference name of the main branch.
TrunkRefName = plumbing.NewBranchReferenceName(Trunk) MainRefName = plumbing.NewBranchReferenceName(Main)
) )
type repoOpts struct { type repoOpts struct {
@ -93,9 +93,9 @@ func InitMemRepo() *Repo {
} }
func (r *Repo) init() error { func (r *Repo) init() error {
h := plumbing.NewSymbolicReference(plumbing.HEAD, TrunkRefName) h := plumbing.NewSymbolicReference(plumbing.HEAD, MainRefName)
if err := r.GitRepo.Storer.SetReference(h); err != nil { if err := r.GitRepo.Storer.SetReference(h); err != nil {
return fmt.Errorf("could not set HEAD to %q: %w", TrunkRefName, err) return fmt.Errorf("could not set HEAD to %q: %w", MainRefName, err)
} }
return nil return nil
} }

View File

@ -193,9 +193,9 @@ access_controls:
_, hash1 := harness.changeCommit("ain't no laws", "toot", nil) _, hash1 := harness.changeCommit("ain't no laws", "toot", nil)
// verifying the first should work, but not the second. // verifying the first should work, but not the second.
if err := harness.repo.VerifyChangeCommit(TrunkRefName, hash0); err != nil { if err := harness.repo.VerifyChangeCommit(MainRefName, hash0); err != nil {
t.Fatalf("first commit %q should be verifiable, but got: %v", hash0, err) t.Fatalf("first commit %q should be verifiable, but got: %v", hash0, err)
} else if err := harness.repo.VerifyChangeCommit(TrunkRefName, hash1); err == nil { } else if err := harness.repo.VerifyChangeCommit(MainRefName, hash1); err == nil {
t.Fatalf("second commit %q should not have been verified", hash1) t.Fatalf("second commit %q should not have been verified", hash1)
} }
@ -212,7 +212,7 @@ accounts:
path: ".dehub/root.asc" path: ".dehub/root.asc"
`}) `})
_, hash2 := harness.changeCommit("Fix the config!", "root", harness.sig) _, hash2 := harness.changeCommit("Fix the config!", "root", harness.sig)
if err := harness.repo.VerifyChangeCommit(TrunkRefName, hash2); err != nil { if err := harness.repo.VerifyChangeCommit(MainRefName, hash2); err != nil {
t.Fatalf("config fix commit %q should be verifiable, but got: %v", hash2, err) t.Fatalf("config fix commit %q should be verifiable, but got: %v", hash2, err)
} }
} }

View File

@ -3,7 +3,7 @@ package sigcred
import "dehub/typeobj" import "dehub/typeobj"
// Credential represents a credential which has been attached to a commit which // Credential represents a credential which has been attached to a commit which
// hopefully will allow it to be included in the trunk. Exactly one field tagged // hopefully will allow it to be included in the main. Exactly one field tagged
// with "type" should be set. // with "type" should be set.
type Credential struct { type Credential struct {
PGPSignature *CredentialPGPSignature `type:"pgp_signature"` PGPSignature *CredentialPGPSignature `type:"pgp_signature"`