mirror of
https://github.com/splitsh/lite.git
synced 2024-06-08 00:32:23 +02:00
Add excluding directories support
This commit is contained in:
parent
eaede0baa4
commit
5dbf39b5b4
16
README.md
16
README.md
|
@ -128,10 +128,18 @@ splitsh-lite --prefix=lib/ --origin=origin/1.0 --path=/path/to/repo
|
||||||
|
|
||||||
Available options:
|
Available options:
|
||||||
|
|
||||||
* `--prefix` is the prefix of the directory to split; you can put the split
|
* `--prefix` is the prefix of the directory to split; the value can be one of
|
||||||
contents in a sub-directory of the target repository by using the
|
the following:
|
||||||
`--prefix=from:to` syntax; split several directories by passing multiple
|
|
||||||
`--prefix` flags;
|
* `from`: the origin directory to split;
|
||||||
|
|
||||||
|
* `from:to`: move the split content to a sub-directory on the target;
|
||||||
|
|
||||||
|
* `from:to:exclude`: exclude a directory from the origin `from` directory
|
||||||
|
(use `from:to:exclude1:exclude2:...` to exclude more than one
|
||||||
|
directory).
|
||||||
|
|
||||||
|
Split several directories by passing multiple `--prefix` flags;
|
||||||
|
|
||||||
* `--path` is the path of the repository to split (current directory by default);
|
* `--path` is the path of the repository to split (current directory by default);
|
||||||
|
|
||||||
|
|
10
main.go
10
main.go
|
@ -24,8 +24,14 @@ func (p *prefixesFlag) Set(value string) error {
|
||||||
parts := strings.Split(value, ":")
|
parts := strings.Split(value, ":")
|
||||||
from := parts[0]
|
from := parts[0]
|
||||||
to := ""
|
to := ""
|
||||||
if len(parts) > 1 {
|
excludes := make([]string, 0)
|
||||||
|
if len(parts) >= 2 {
|
||||||
to = parts[1]
|
to = parts[1]
|
||||||
|
if len(parts) > 2 {
|
||||||
|
for _, exclude := range parts[2:] {
|
||||||
|
excludes = append(excludes, exclude)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// value must be unique
|
// value must be unique
|
||||||
|
@ -36,7 +42,7 @@ func (p *prefixesFlag) Set(value string) error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
*p = append(*p, &splitter.Prefix{From: from, To: to})
|
*p = append(*p, &splitter.Prefix{From: from, To: to, Excludes: excludes})
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -77,6 +77,9 @@ func key(config *Config) []byte {
|
||||||
for _, prefix := range config.Prefixes {
|
for _, prefix := range config.Prefixes {
|
||||||
io.WriteString(h, prefix.From)
|
io.WriteString(h, prefix.From)
|
||||||
io.WriteString(h, prefix.To)
|
io.WriteString(h, prefix.To)
|
||||||
|
for _, exclude := range prefix.Excludes {
|
||||||
|
io.WriteString(h, exclude)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return h.Sum(nil)
|
return h.Sum(nil)
|
||||||
|
|
|
@ -11,8 +11,9 @@ import (
|
||||||
|
|
||||||
// Prefix represents which paths to split
|
// Prefix represents which paths to split
|
||||||
type Prefix struct {
|
type Prefix struct {
|
||||||
From string
|
From string
|
||||||
To string
|
To string
|
||||||
|
Excludes []string
|
||||||
}
|
}
|
||||||
|
|
||||||
// Config represents a split configuration
|
// Config represents a split configuration
|
||||||
|
|
|
@ -61,13 +61,17 @@ func newState(config *Config, result *Result) (*state, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if config.Debug {
|
if config.Debug {
|
||||||
state.logger.Printf("Splitting %s\n", state.originBranch)
|
state.logger.Printf("Splitting %s", state.originBranch)
|
||||||
for _, v := range config.Prefixes {
|
for _, v := range config.Prefixes {
|
||||||
to := v.To
|
to := v.To
|
||||||
if to == "" {
|
if to == "" {
|
||||||
to = "ROOT"
|
to = "ROOT"
|
||||||
}
|
}
|
||||||
state.logger.Printf(" From \"%s\" to \"%s\"\n", v.From, to)
|
state.logger.Printf(` From "%s" to "%s"`, v.From, to)
|
||||||
|
if (len(v.Excludes)) == 0 {
|
||||||
|
} else {
|
||||||
|
state.logger.Printf(` Excluding "%s"`, strings.Join(v.Excludes, `", "`))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -79,7 +83,7 @@ func newState(config *Config, result *Result) (*state, error) {
|
||||||
|
|
||||||
// simplePrefix contains the prefix when there is only one
|
// simplePrefix contains the prefix when there is only one
|
||||||
// with an empty value (target)
|
// with an empty value (target)
|
||||||
if len(config.Prefixes) == 1 && config.Prefixes[0].To == "" {
|
if len(config.Prefixes) == 1 && config.Prefixes[0].To == "" && len(config.Prefixes[0].Excludes) == 0 {
|
||||||
state.simplePrefix = config.Prefixes[0].From
|
state.simplePrefix = config.Prefixes[0].From
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -284,6 +288,14 @@ func (s *state) treeByPaths(tree *git.Tree) (*git.Tree, error) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if len(prefix.Excludes) > 0 {
|
||||||
|
prunedTree, err := s.pruneTree(splitTree, prefix.Excludes)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
splitTree = prunedTree
|
||||||
|
}
|
||||||
|
|
||||||
// adding the prefix
|
// adding the prefix
|
||||||
if prefix.To != "" {
|
if prefix.To != "" {
|
||||||
prefixedTree, err = s.addPrefixToTree(splitTree, prefix.To)
|
prefixedTree, err = s.addPrefixToTree(splitTree, prefix.To)
|
||||||
|
@ -360,6 +372,53 @@ func (s *state) addPrefixToTree(tree *git.Tree, prefix string) (*git.Tree, error
|
||||||
return prefixedTree, nil
|
return prefixedTree, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *state) pruneTree(tree *git.Tree, excludes []string) (*git.Tree, error) {
|
||||||
|
var err error
|
||||||
|
treeBuilder, err := s.repo.TreeBuilder()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer treeBuilder.Free()
|
||||||
|
|
||||||
|
err = tree.Walk(func(path string, entry *git.TreeEntry) error {
|
||||||
|
// always add files at the root directory
|
||||||
|
if entry.Type == git.ObjectBlob {
|
||||||
|
if err := treeBuilder.Insert(entry.Name, entry.Id, git.FilemodeBlob); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if entry.Type != git.ObjectTree {
|
||||||
|
// should never happen
|
||||||
|
return fmt.Errorf("Unexpected entry %s/%s (type %s)", path, entry.Name, entry.Type)
|
||||||
|
}
|
||||||
|
|
||||||
|
// exclude directory in excludes
|
||||||
|
for _, exclude := range excludes {
|
||||||
|
if entry.Name == exclude {
|
||||||
|
return git.TreeWalkSkip
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := treeBuilder.Insert(entry.Name, entry.Id, git.FilemodeTree); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return git.TreeWalkSkip
|
||||||
|
})
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
treeOid, err := treeBuilder.Write()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return s.repo.LookupTree(treeOid)
|
||||||
|
}
|
||||||
|
|
||||||
func (s *state) copyOrSkip(rev *git.Commit, tree *git.Tree, newParents []*git.Oid) (*git.Oid, bool, error) {
|
func (s *state) copyOrSkip(rev *git.Commit, tree *git.Tree, newParents []*git.Oid) (*git.Oid, bool, error) {
|
||||||
var identical, nonIdentical *git.Oid
|
var identical, nonIdentical *git.Oid
|
||||||
var gotParents []*git.Oid
|
var gotParents []*git.Oid
|
||||||
|
|
Loading…
Reference in a new issue