1// Copyright 2014 The Go Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style 3// license that can be found in the LICENSE file. 4 5package main 6 7import ( 8 "reflect" 9 "strings" 10 "testing" 11) 12 13func TestCurrentBranch(t *testing.T) { 14 gt := newGitTest(t) 15 defer gt.done() 16 17 t.Logf("on main") 18 checkCurrentBranch(t, "main", "origin/main", false, "", "") 19 20 t.Logf("on newbranch") 21 trun(t, gt.client, "git", "checkout", "--no-track", "-b", "newbranch") 22 checkCurrentBranch(t, "newbranch", "origin/main", false, "", "") 23 24 t.Logf("making change") 25 write(t, gt.client+"/file", "i made a change", 0644) 26 trun(t, gt.client, "git", "commit", "-a", "-m", "My change line.\n\nChange-Id: I0123456789abcdef0123456789abcdef\n") 27 checkCurrentBranch(t, "newbranch", "origin/main", true, "I0123456789abcdef0123456789abcdef", "My change line.") 28 29 t.Logf("on dev.branch") 30 trun(t, gt.client, "git", "checkout", "-t", "-b", "dev.branch", "origin/dev.branch") 31 checkCurrentBranch(t, "dev.branch", "origin/dev.branch", false, "", "") 32 33 t.Logf("on newdev") 34 trun(t, gt.client, "git", "checkout", "-t", "-b", "newdev", "origin/dev.branch") 35 checkCurrentBranch(t, "newdev", "origin/dev.branch", false, "", "") 36 37 t.Logf("making change") 38 write(t, gt.client+"/file", "i made another change", 0644) 39 trun(t, gt.client, "git", "commit", "-a", "-m", "My other change line.\n\nChange-Id: I1123456789abcdef0123456789abcdef\n") 40 checkCurrentBranch(t, "newdev", "origin/dev.branch", true, "I1123456789abcdef0123456789abcdef", "My other change line.") 41 42 t.Logf("detached head mode") 43 trun(t, gt.client, "git", "checkout", "main^0") 44 checkCurrentBranch(t, "HEAD", "", false, "", "") 45 trun(t, gt.client, "git", "checkout", "dev.branch^0") 46 checkCurrentBranch(t, "HEAD", "origin/dev.branch", false, "", "") 47} 48 49func checkCurrentBranch(t *testing.T, name, origin string, hasPending bool, changeID, subject string) { 50 t.Helper() 51 b := CurrentBranch() 52 if b.Name != name { 53 t.Errorf("b.Name = %q, want %q", b.Name, name) 54 } 55 if x := b.OriginBranch(); x != origin { 56 t.Errorf("b.OriginBranch() = %q, want %q", x, origin) 57 } 58 if x := b.HasPendingCommit(); x != hasPending { 59 t.Errorf("b.HasPendingCommit() = %v, want %v", x, hasPending) 60 } 61 if work := b.Pending(); len(work) > 0 { 62 c := work[0] 63 if x := c.ChangeID; x != changeID { 64 t.Errorf("b.Pending()[0].ChangeID = %q, want %q", x, changeID) 65 } 66 if x := c.Subject; x != subject { 67 t.Errorf("b.Pending()[0].Subject = %q, want %q", x, subject) 68 } 69 } 70} 71 72func TestLocalBranches(t *testing.T) { 73 gt := newGitTest(t) 74 defer gt.done() 75 76 t.Logf("on main") 77 checkLocalBranches(t, "main") 78 79 t.Logf("on dev branch") 80 trun(t, gt.client, "git", "checkout", "-b", "newbranch") 81 checkLocalBranches(t, "main", "newbranch") 82 83 t.Logf("detached head mode") 84 trun(t, gt.client, "git", "checkout", "HEAD^0") 85 checkLocalBranches(t, "HEAD", "main", "newbranch") 86} 87 88func checkLocalBranches(t *testing.T, want ...string) { 89 var names []string 90 branches := LocalBranches() 91 for _, b := range branches { 92 names = append(names, b.Name) 93 } 94 if !reflect.DeepEqual(names, want) { 95 t.Errorf("LocalBranches() = %v, want %v", names, want) 96 } 97} 98 99func TestAmbiguousRevision(t *testing.T) { 100 gt := newGitTest(t) 101 defer gt.done() 102 gt.work(t) 103 104 t.Logf("creating file paths that conflict with revision parameters") 105 mkdir(t, gt.client+"/origin") 106 write(t, gt.client+"/origin/main..work", "Uh-Oh! SpaghettiOs", 0644) 107 mkdir(t, gt.client+"/work..origin") 108 write(t, gt.client+"/work..origin/main", "Be sure to drink your Ovaltine", 0644) 109 110 b := CurrentBranch() 111 b.Submitted("I123456789") 112} 113 114func TestBranchpoint(t *testing.T) { 115 gt := newGitTest(t) 116 defer gt.done() 117 118 // Get hash corresponding to checkout (known to server). 119 hash := strings.TrimSpace(trun(t, gt.client, "git", "rev-parse", "HEAD")) 120 121 // Any work we do after this point should find hash as branchpoint. 122 for i := 0; i < 4; i++ { 123 testMain(t, "branchpoint") 124 t.Logf("numCommits=%d", i) 125 testPrintedStdout(t, hash) 126 testNoStderr(t) 127 128 gt.work(t) 129 } 130} 131 132func TestRebaseWork(t *testing.T) { 133 gt := newGitTest(t) 134 defer gt.done() 135 136 // Get hash corresponding to checkout (known to server). 137 // Any work we do after this point should find hash as branchpoint. 138 hash := strings.TrimSpace(trun(t, gt.client, "git", "rev-parse", "HEAD")) 139 140 testMainDied(t, "rebase-work", "-n") 141 testPrintedStderr(t, "no pending work") 142 143 write(t, gt.client+"/file", "uncommitted", 0644) 144 testMainDied(t, "rebase-work", "-n") 145 testPrintedStderr(t, "cannot rebase with uncommitted work") 146 147 gt.work(t) 148 149 for i := 0; i < 4; i++ { 150 testMain(t, "rebase-work", "-n") 151 t.Logf("numCommits=%d", i) 152 testPrintedStderr(t, "git rebase -i "+hash) 153 154 gt.work(t) 155 } 156} 157 158func TestBranchpointMerge(t *testing.T) { 159 gt := newGitTest(t) 160 defer gt.done() 161 162 // commit more work on main 163 write(t, gt.server+"/file", "more work", 0644) 164 trun(t, gt.server, "git", "commit", "-m", "work", "file") 165 166 // update client 167 trun(t, gt.client, "git", "checkout", "main") 168 trun(t, gt.client, "git", "pull") 169 170 hash := strings.TrimSpace(trun(t, gt.client, "git", "rev-parse", "HEAD")) 171 172 // Merge dev.branch but delete the codereview.cfg that comes in, 173 // or else we'll think we are on the wrong branch. 174 trun(t, gt.client, "git", "merge", "-m", "merge", "origin/dev.branch") 175 trun(t, gt.client, "git", "rm", "codereview.cfg") 176 trun(t, gt.client, "git", "commit", "-m", "rm codereview.cfg") 177 178 // check branchpoint is old head (despite this commit having two parents) 179 bp := CurrentBranch().Branchpoint() 180 if bp != hash { 181 t.Logf("branches:\n%s", trun(t, gt.client, "git", "branch", "-a", "-v")) 182 t.Logf("log:\n%s", trun(t, gt.client, "git", "log", "--graph", "--decorate")) 183 t.Logf("log origin/main..HEAD:\n%s", trun(t, gt.client, "git", "log", "origin/main..HEAD")) 184 t.Fatalf("branchpoint=%q, want %q", bp, hash) 185 } 186} 187