added support for Git 1.9 behavior

This commit is contained in:
Fabien Potencier 2016-07-09 10:17:17 +02:00
parent ec01ec9e13
commit 85bc0419ee
6 changed files with 119 additions and 13 deletions

View file

@ -116,9 +116,9 @@ Available options:
* `--scratch` flushes the cache (useful when a branch is force pushed or in
case of corruption)
* `--legacy` simulates old versions of `git subtree split` where `sha1`s
for the split commits were computed differently (useful if you are switching
from the git command to **splitsh-lite**).
* `--git` simulates old versions of `git subtree split`. **splitsh** generates
the same `sha1`s as the latest version of Git by default (`latest`).
Simulate old versions of Git by using `<1.8.2` or `<2.8.0`.
**splitsh** provides more features including a sanity checker, GitHub integration
for real-time splitting, tagging management and synchronization, and more.

19
main.go
View file

@ -37,7 +37,7 @@ func (p *prefixesFlag) Set(value string) error {
}
var prefixes prefixesFlag
var origin, target, commit, path string
var origin, target, commit, path, git string
var scratch, debug, quiet, legacy, progress bool
func init() {
@ -49,7 +49,8 @@ func init() {
flag.BoolVar(&scratch, "scratch", false, "Flush the cache (optional)")
flag.BoolVar(&debug, "debug", false, "Enable the debug mode (optional)")
flag.BoolVar(&quiet, "quiet", false, "Suppress the output (optional)")
flag.BoolVar(&legacy, "legacy", false, "Enable the legacy mode for projects migrating from an old version of git subtree split (optional)")
flag.BoolVar(&legacy, "legacy", false, "[DEPRECATED] Enable the legacy mode for projects migrating from an old version of git subtree split (optional)")
flag.StringVar(&git, "git", "latest", "Simulate a given version of Git (optional)")
flag.BoolVar(&progress, "progress", false, "Show progress bar (optional, cannot be enabled when debug is enabled)")
}
@ -61,6 +62,18 @@ func main() {
os.Exit(1)
}
supportedGitVersions := map[string]int{"<1.8.2": 1, "<2.8.0": 2, "latest": 3}
gitVersion, ok := supportedGitVersions[git]
if !ok {
fmt.Println(`The --git flag can be "<1.8.2", "<2.8.0", or "latest"`)
os.Exit(1)
}
if legacy {
fmt.Fprintf(os.Stderr, `The --legacy option is deprecated (use --git="<1.8.2" instead)`)
gitVersion = 1
}
config := &splitter.Config{
Path: path,
Origin: origin,
@ -69,7 +82,7 @@ func main() {
Commit: commit,
Debug: debug && !quiet,
Scratch: scratch,
Legacy: legacy,
Git: gitVersion,
}
result := &splitter.Result{}

View file

@ -85,6 +85,71 @@ fi
cd ../
rm -rf merge
mkdir -p merge/src
cd merge
git init > /dev/null
export GIT_AUTHOR_NAME="Sammy Cobol"
export GIT_AUTHOR_EMAIL="<sammy.cobol@example.com>"
export GIT_AUTHOR_DATE="Sat, 24 Nov 1973 19:01:01 +0200"
export GIT_COMMITTER_NAME="Fred Foobar"
export GIT_COMMITTER_EMAIL="<fred.foobar@example.com>"
export GIT_COMMITTER_DATE="Sat, 24 Nov 1973 19:01:01 +0200"
echo -e "a\n\nb\n\nc\n\n" > src/foo
git add src/foo
git commit -m"init" > /dev/null
git co -b branch1 2> /dev/null
export GIT_AUTHOR_DATE="Sat, 24 Nov 1973 19:02:02 +0200"
export GIT_COMMITTER_DATE="Sat, 24 Nov 1973 19:02:02 +0200"
echo -e "a\n\nb\nchange 2\nc\n\n" > src/foo
git commit -a -m"change 2" > /dev/null
export GIT_AUTHOR_DATE="Sat, 24 Nov 1973 19:02:02 +0200"
export GIT_COMMITTER_DATE="Sat, 24 Nov 1973 19:02:02 +0200"
echo -e "a\n\nb\nchange 2\nc\nchange 3\n" > src/foo
git commit -a -m"change 3" > /dev/null
git co master 2> /dev/null
export GIT_AUTHOR_DATE="Sat, 24 Nov 1973 19:02:02 +0200"
export GIT_COMMITTER_DATE="Sat, 24 Nov 1973 19:02:02 +0200"
echo -e "a\nchange 1\nb\n\nc\n\n" > src/foo
git commit -a -m"change 1" > /dev/null
git co -b branch2 2> /dev/null
export GIT_AUTHOR_DATE="Sat, 24 Nov 1973 19:02:02 +0200"
export GIT_COMMITTER_DATE="Sat, 24 Nov 1973 19:02:02 +0200"
echo -e "a\n\nb\nchange 2\nc\n\n" > src/foo
git commit -a -m"change 2" > /dev/null
git co master 2> /dev/null
git co -b branch3 2> /dev/null
git merge branch1 --no-edit > /dev/null
git merge branch2 --no-edit -s ours > /dev/null
GIT_SUBTREE_SPLIT_SHA1_2="a2c4245703f8dac149ab666242a12e1d4b2510d9"
GIT_SUBTREE_SPLIT_SHA1_3="ba0dab2c4e99d68d11088f2c556af92851e93b14"
GIT_SPLITSH_SHA1_2=`$GOPATH/src/github.com/splitsh/lite/lite --git="<2.8.0" --prefix=src/ --quiet`
GIT_SPLITSH_SHA1_3=`$GOPATH/src/github.com/splitsh/lite/lite --prefix=src/ --quiet`
if [ "$GIT_SUBTREE_SPLIT_SHA1_2" == "$GIT_SUBTREE_SPLIT_SHA1_2" ]; then
echo "OK ($GIT_SUBTREE_SPLIT_SHA1_2 == $GIT_SUBTREE_SPLIT_SHA1_2)"
else
echo "OK ($GIT_SUBTREE_SPLIT_SHA1_2 != $GIT_SUBTREE_SPLIT_SHA1_2)"
exit 1
fi
if [ "$GIT_SUBTREE_SPLIT_SHA1_3" == "$GIT_SUBTREE_SPLIT_SHA1_3" ]; then
echo "OK ($GIT_SUBTREE_SPLIT_SHA1_3 == $GIT_SUBTREE_SPLIT_SHA1_3)"
else
echo "OK ($GIT_SUBTREE_SPLIT_SHA1_3 != $GIT_SUBTREE_SPLIT_SHA1_3)"
exit 1
fi
cd ../
# run on some Open-Source repositories
if [ ! -d Twig ]; then
git clone https://github.com/twigphp/Twig > /dev/null

View file

@ -5,6 +5,7 @@ import (
"fmt"
"io"
"path/filepath"
"strconv"
"time"
"github.com/boltdb/bolt"
@ -57,9 +58,7 @@ func key(config *Config) []byte {
io.WriteString(h, "oldest")
}
if config.Legacy {
io.WriteString(h, "legacy")
}
io.WriteString(h, strconv.Itoa(config.Git))
for _, prefix := range config.Prefixes {
io.WriteString(h, prefix.From)

View file

@ -22,9 +22,9 @@ type Config struct {
Origin string
Commit string
Target string
Git int
Debug bool
Scratch bool
Legacy bool
// for advanced usage only
// naming and types subject to change anytime!

View file

@ -358,7 +358,7 @@ func (s *state) addPrefixToTree(tree *git.Tree, prefix string) (*git.Tree, error
}
func (s *state) copyOrSkip(rev *git.Commit, tree *git.Tree, newParents []*git.Oid) (*git.Oid, bool, error) {
var identical *git.Oid
var identical, nonIdentical *git.Oid
var gotParents []*git.Oid
var p []*git.Commit
for _, parent := range newParents {
@ -373,6 +373,8 @@ func (s *state) copyOrSkip(rev *git.Commit, tree *git.Tree, newParents []*git.Oi
if 0 == ptree.Cmp(tree.Id()) {
// an identical parent could be used in place of this rev.
identical = parent
} else {
nonIdentical = parent
}
// sometimes both old parents map to the same newparent
@ -396,7 +398,34 @@ func (s *state) copyOrSkip(rev *git.Commit, tree *git.Tree, newParents []*git.Oi
}
}
if nil != identical {
copyCommit := false
if s.config.Git > 2 && nil != identical && nil != nonIdentical {
revWalk, err := s.repo.Walk()
if err != nil {
return nil, false, fmt.Errorf("Impossible to walk the repository: %s", err)
}
s.repoMu.Lock()
defer s.repoMu.Unlock()
err = revWalk.PushRange(fmt.Sprintf("%s..%s", identical, nonIdentical))
if err != nil {
return nil, false, fmt.Errorf("Impossible to determine split range: %s", err)
}
err = revWalk.Iterate(func(rev *git.Commit) bool {
// we need to preserve history along the other branch
copyCommit = true
return false
})
if err != nil {
return nil, false, err
}
revWalk.Free()
}
if nil != identical && copyCommit == false {
return identical, false, nil
}
@ -434,7 +463,7 @@ func (s *state) copyCommit(rev *git.Commit, tree *git.Tree, parents []*git.Commi
}
message := rev.Message()
if s.config.Legacy {
if s.config.Git == 1 {
message = s.legacyMessage(rev)
}