-
Notifications
You must be signed in to change notification settings - Fork 535
Submodules init and update #270
Changes from 1 commit
498dbf7
b3b6e51
b18d649
c551c29
940a16c
f8b5557
65351f8
7e990a8
09110d8
d6a6dec
ed288b3
790fbda
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -9,9 +9,18 @@ import ( | |
"srcd.works/go-git.v4/plumbing/transport" | ||
) | ||
|
||
// SubmoduleRescursivity defines how depth will affect any submodule recursive | ||
// operation | ||
type SubmoduleRescursivity int | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. alternative name: There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I just change the time to uint, infinity by itself is not allowed, a number should be given always, even if is very high |
||
|
||
const ( | ||
// DefaultRemoteName name of the default Remote, just like git command | ||
DefaultRemoteName = "origin" | ||
|
||
// NoRecursivity disables the recursion for a submodule operation | ||
NoRecursivity SubmoduleRescursivity = 0 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. alternative: |
||
// DefaultRecursivity allow recursion in a submodule operation | ||
DefaultRecursivity SubmoduleRescursivity = 10 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. alternative: |
||
) | ||
|
||
var ( | ||
|
@@ -32,10 +41,10 @@ type CloneOptions struct { | |
SingleBranch bool | ||
// Limit fetching to the specified number of commits | ||
Depth int | ||
// RecursiveSubmodules after the clone is created, initialize all submodules | ||
// RecurseSubmodules after the clone is created, initialize all submodules | ||
// within, using their default settings. This option is ignored if the | ||
// cloned repository does not have a worktree | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. end the paragraph with a full stop. |
||
RecursiveSubmodules bool | ||
RecurseSubmodules SubmoduleRescursivity | ||
// Progress is where the human readable information sent by the server is | ||
// stored, if nil nothing is stored and the capability (if supported) | ||
// no-progress, is sent to the server to avoid send this information | ||
|
@@ -71,6 +80,9 @@ type PullOptions struct { | |
Depth int | ||
// Auth credentials, if required, to use with the remote repository | ||
Auth transport.AuthMethod | ||
// RecurseSubmodules controls if new commits of all populated submodules | ||
// should be fetched too | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. End the sentence with a full stop. |
||
RecurseSubmodules SubmoduleRescursivity | ||
// Progress is where the human readable information sent by the server is | ||
// stored, if nil nothing is stored and the capability (if supported) | ||
// no-progress, is sent to the server to avoid send this information | ||
|
@@ -152,3 +164,16 @@ func (o *PushOptions) Validate() error { | |
|
||
return nil | ||
} | ||
|
||
// SubmoduleUpdateOptions describes how a submodule update should be performed | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add full stop. |
||
type SubmoduleUpdateOptions struct { | ||
// Init initializes the submodules recorded in the index | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add full stop. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This needs much better explanation. It is a bool, but does not make sense with the comment. |
||
Init bool | ||
// NoFetch tell to the update command to don’t fetch new objects from the | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
// remote site. | ||
NoFetch bool | ||
// RecurseSubmodules the update is performed not only in the submodules of | ||
// the current repository but also in any nested submodules inside those | ||
// submodules (and so on). Until the SubmoduleRescursivity is reached. | ||
RecurseSubmodules SubmoduleRescursivity | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,60 +1,141 @@ | ||
package git | ||
|
||
import ( | ||
"errors" | ||
|
||
"srcd.works/go-git.v4/config" | ||
"srcd.works/go-git.v4/plumbing" | ||
) | ||
|
||
var ( | ||
ErrSubmoduleAlreadyInitialized = errors.New("submodule already initialized") | ||
ErrSubmoduleNotInitialized = errors.New("submodule not initialized") | ||
) | ||
|
||
// Submodule a submodule allows you to keep another Git repository in a | ||
// subdirectory of your repository. | ||
type Submodule struct { | ||
m *config.Submodule | ||
initialized bool | ||
|
||
c *config.Submodule | ||
w *Worktree | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Change this to WorkTree. |
||
// r is the submodule repository | ||
r *Repository | ||
} | ||
|
||
// Config returns the submodule config | ||
func (s *Submodule) Config() *config.Submodule { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why not make m public instead of a getter? |
||
return s.m | ||
return s.c | ||
} | ||
|
||
// Init initialize the submodule reading the recoreded Entry in the index for | ||
// the given submodule | ||
func (s *Submodule) Init() error { | ||
e, err := s.w.readIndexEntry(s.m.Path) | ||
cfg, err := s.w.r.Storer.Config() | ||
if err != nil { | ||
return err | ||
} | ||
|
||
_, err = s.r.CreateRemote(&config.RemoteConfig{ | ||
_, ok := cfg.Submodules[s.c.Name] | ||
if ok { | ||
return ErrSubmoduleAlreadyInitialized | ||
} | ||
|
||
s.initialized = true | ||
|
||
cfg.Submodules[s.c.Name] = s.c | ||
return s.w.r.Storer.SetConfig(cfg) | ||
} | ||
|
||
// Repository returns the Repository represented by this submodule | ||
func (s *Submodule) Repository() (*Repository, error) { | ||
storer, err := s.w.r.Storer.Module(s.c.Name) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
_, err = storer.Reference(plumbing.HEAD) | ||
if err != nil && err != plumbing.ErrReferenceNotFound { | ||
return nil, err | ||
} | ||
|
||
worktree := s.w.fs.Dir(s.c.Path) | ||
if err == nil { | ||
return Open(storer, worktree) | ||
} | ||
|
||
r, err := Init(storer, worktree) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
_, err = r.CreateRemote(&config.RemoteConfig{ | ||
Name: DefaultRemoteName, | ||
URL: s.m.URL, | ||
URL: s.c.URL, | ||
}) | ||
|
||
return r, err | ||
} | ||
|
||
// Update the registered submodule to match what the superproject expects, the | ||
// submodule should be initilized first calling the Init method or setting in | ||
// the options SubmoduleUpdateOptions.Init equals true | ||
func (s *Submodule) Update(o *SubmoduleUpdateOptions) error { | ||
if !s.initialized && !o.Init { | ||
return ErrSubmoduleNotInitialized | ||
} | ||
|
||
if !s.initialized && o.Init { | ||
if err := s.Init(); err != nil { | ||
return err | ||
} | ||
} | ||
|
||
e, err := s.w.readIndexEntry(s.c.Path) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
return s.fetchAndCheckout(e.Hash) | ||
r, err := s.Repository() | ||
if err != nil { | ||
return err | ||
} | ||
|
||
if err := s.fetchAndCheckout(r, o, e.Hash); err != nil { | ||
return err | ||
} | ||
|
||
return s.doRecrusiveUpdate(r, o) | ||
} | ||
|
||
// Update the registered submodule to match what the superproject expects | ||
func (s *Submodule) Update() error { | ||
e, err := s.w.readIndexEntry(s.m.Path) | ||
func (s *Submodule) doRecrusiveUpdate(r *Repository, o *SubmoduleUpdateOptions) error { | ||
if o.RecurseSubmodules == NoRecursivity { | ||
return nil | ||
} | ||
|
||
w, err := r.Worktree() | ||
if err != nil { | ||
return err | ||
} | ||
|
||
return s.fetchAndCheckout(e.Hash) | ||
l, err := w.Submodules() | ||
if err != nil { | ||
return err | ||
} | ||
|
||
new := &SubmoduleUpdateOptions{} | ||
*new = *o | ||
new.RecurseSubmodules-- | ||
return l.Update(new) | ||
} | ||
|
||
func (s *Submodule) fetchAndCheckout(hash plumbing.Hash) error { | ||
if err := s.r.Fetch(&FetchOptions{}); err != nil && err != NoErrAlreadyUpToDate { | ||
return err | ||
func (s *Submodule) fetchAndCheckout(r *Repository, o *SubmoduleUpdateOptions, hash plumbing.Hash) error { | ||
if !o.NoFetch { | ||
err := r.Fetch(&FetchOptions{}) | ||
if err != nil && err != NoErrAlreadyUpToDate { | ||
return err | ||
} | ||
} | ||
|
||
w, err := s.r.Worktree() | ||
w, err := r.Worktree() | ||
if err != nil { | ||
return err | ||
} | ||
|
@@ -64,13 +145,13 @@ func (s *Submodule) fetchAndCheckout(hash plumbing.Hash) error { | |
} | ||
|
||
head := plumbing.NewHashReference(plumbing.HEAD, hash) | ||
return s.r.Storer.SetReference(head) | ||
return r.Storer.SetReference(head) | ||
} | ||
|
||
// Submodules list of several submodules from the same repository | ||
type Submodules []*Submodule | ||
|
||
// Init initialize the submodule recorded in the index | ||
// Init initializes the submodules in this list | ||
func (s Submodules) Init() error { | ||
for _, sub := range s { | ||
if err := sub.Init(); err != nil { | ||
|
@@ -80,3 +161,14 @@ func (s Submodules) Init() error { | |
|
||
return nil | ||
} | ||
|
||
// Update updates all the submodules in this list | ||
func (s Submodules) Update(o *SubmoduleUpdateOptions) error { | ||
for _, sub := range s { | ||
if err := sub.Update(o); err != nil { | ||
return err | ||
} | ||
} | ||
|
||
return nil | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would change the name from
DefaultRecursivity
toDefaultRecurseModules
orDefaultSubmoduleRecursivity
or something like that, so that it does not get confused with other parameters related with recursivite of non-submodule stuff (e.g. reference resolution).