-
Notifications
You must be signed in to change notification settings - Fork 534
Conversation
Current coverage is 76.96% (diff: 70.88%)@@ master #178 diff @@
==========================================
Files 92 92
Lines 5793 5940 +147
Methods 0 0
Messages 0 0
Branches 0 0
==========================================
+ Hits 4510 4572 +62
- Misses 810 882 +72
- Partials 473 486 +13
|
) | ||
|
||
func main() { | ||
if len(os.Args) != 4 { |
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 created a helper function for the args parse:
CheckArgs("<directory>", "<remote-url>", "<refspec>")
directory := os.Args[1]
remoteUrl := os.Args[2]
} | ||
|
||
repo, err := git.NewFilesystemRepository(repoPath) | ||
if err != 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.
The err are checked using CheckIfError(err)
panic(err) | ||
} | ||
|
||
if err := repo.Push(&git.PushOptions{ |
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.
And is supposed to illustrate the code with his homologue at git
Info("git clone %s %s", url, directory)
|
||
// Remote represents a connection to a remote repository | ||
type Remote struct { | ||
c *config.RemoteConfig | ||
r *Repository |
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.
if you add the Repository then remove the Storer
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.
it will not be present in the next version (after rebase).
// Connect with the endpoint | ||
func (r *Remote) Connect() error { | ||
// ConnectFetch connects to the remote and starts a fetch session. | ||
func (r *Remote) ConnectFetch() error { |
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.
make private this methods
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.
they are gone after the next rebase
return fmt.Errorf("no refspec given") | ||
} | ||
|
||
if err := o.Validate(); err != 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.
the validation should be the first thing, doesn't worth to make any operation if the o are not valid
return err | ||
} | ||
|
||
if err := iter.ForEach(func(ref *plumbing.Reference) error { |
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 prefer not having the if and the ForEach with the closure in the same line
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 find hard to understand at a glance what operation are we doing on each element in the collection.
Can we define the function separately, give it a good name, and call it here instead?
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.
Done.
@@ -318,10 +511,19 @@ func (r *Remote) References() (storer.ReferenceIter, error) { | |||
return r.refs.IterReferences() | |||
} | |||
|
|||
// Disconnect from the remote and save the config | |||
// Disconnect from the remote server. Calling Disconnect on a disconnected | |||
// remote has no effect. | |||
func (r *Remote) Disconnect() error { |
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.
make it private
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.
Not until we make Fetch atomic, which currently it is not.
} | ||
|
||
// Validate validate the fields and set the default values | ||
func (o *PushOptions) Validate() error { |
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.
Do we want to have invalid PushOptions values around in our program?, if not, I would make PushOptions
fields private, provide a ctor for it (that checks for validity) and add some getters (if they are needed).
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.
Why is Validate
not used in the example?
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.
See the above comment, I'm using the same conventions for Validate as in the rest of the code base. The example doesn't use Validate, the user doesn't need to call it, since it's always called by porcelain methods when they get options.
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.
👍
panic(err) | ||
} | ||
|
||
if _, err := repo.CreateRemote(&config.RemoteConfig{ |
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 find this confusing: Why pushing to a remote repository creates a remote in the current repository?
Should this be a different (an optional) operation from pushing?, it is a nasty side effect.
In other words, can we push to a repository that is not a remote? why not?
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.
Yeah, I'm changing the example to do a more standard/intuitive thing.
// PushOptions describe how a push should be performed. | ||
type PushOptions struct { | ||
// RemoteName is the name of the remote to be pushed to. | ||
RemoteName string |
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.
This should be a URL, not a remote, I think.
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.
git-push supports both, either getting a remote name or getting a URL directly (i.e. push to a repository without adding a remote). However, at the moment, we implent only pull/push by remote name.
Adding support for direct URL would be good (for clone/pull/push/fetch), but it seems work for a separate PR.
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.
👍
s Storer | ||
p sideband.Progress | ||
|
||
// cache fields, there during the connection is open | ||
endpoint transport.Endpoint | ||
client transport.Client | ||
fetchSession transport.FetchPackSession | ||
sendSession transport.SendPackSession | ||
session transport.Session |
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.
can you explain the difference between session
and the other two (sendSession
and fetchSession
)?
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.
session can be either fetchSession / sendSession. It's used for some common operations.
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.
This will go away if we merge #185 first.
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.
👍
// TODO: Support pushing tags. | ||
// TODO: Check if force update is given, otherwise reject non-fast forward. | ||
func (r *Remote) Push(o *PushOptions) (err error) { | ||
if o.RemoteName == "" { |
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 though PushOptions.Validate
didn't allow for empty strings in the remote name. I'm confused.
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.
It is allowed to pass empty remote directly to Remote, since the name is already set in the remote itself and it cannot push to a different Remote.
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.
👍
return err | ||
} | ||
|
||
if err := iter.ForEach(func(ref *plumbing.Reference) error { |
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 find hard to understand at a glance what operation are we doing on each element in the collection.
Can we define the function separately, give it a good name, and call it here instead?
@@ -294,6 +423,70 @@ func (r *Remote) buildFetchedTags() error { | |||
}) | |||
} | |||
|
|||
func (r *Remote) getHaves(refs memory.ReferenceStorage) []plumbing.Hash { |
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.
why is this a method of Remote
instead of a free function?
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.
Changed.
@@ -275,6 +269,25 @@ func (r *Repository) Pull(o *PullOptions) error { | |||
return r.createReferences(head) | |||
} | |||
|
|||
// Push pushes changes to a remote. | |||
func (r *Repository) Push(o *PushOptions) error { | |||
if o.RemoteName == "" { |
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.
Again, this was supposed to be part of Validate.
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.
Right.
return err | ||
} | ||
|
||
if err := remote.ConnectPush(); err != 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 think Connect should not be needed here, unless you want to do other things over the connection in addition to Push.
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 did it this way to keep symmetry with the Fetch implementation. Although both should be changed to have atomic operations without Connect/Disconnect at all.
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.
👍
RefSpecs []config.RefSpec | ||
} | ||
|
||
// Validate validate the fields and set the default values |
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.
Based on its name, I find weird that Validate set anything, I would expect it to have a non-pointer receiver and just return true or false.
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'm following the same convention that we are using for a lot of objects in go-git (check other Validate methods). We can discuss changing them as a separate issue, not related to this PR.
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.
👍
|
||
"gopkg.in/src-d/go-git.v4" | ||
"gopkg.in/src-d/go-git.v4/config" | ||
. "gopkg.in/src-d/go-git.v4/examples" |
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.
missing space
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.
why? they are all internal imports.
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.
oops, you're right, I just saw the period and i thought that was go-check or something... 👍
@smola rebase |
@@ -20,6 +25,16 @@ var args = map[string][]string{ | |||
"clone": []string{defaultURL, tempFolder()}, | |||
"progress": []string{defaultURL, tempFolder()}, | |||
"open": []string{filepath.Join(cloneRepository(defaultURL, tempFolder()), ".git")}, | |||
"push": []string{ |
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.
can you create a function?
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.
done
setRemote(local, fmt.Sprintf("file://%s", remote)) | ||
return local | ||
}(), | ||
"origin", |
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.
the default RemoteName is "origin" should to omit this arg to simplify the example?
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.
done, reduced to just push origin with default refspec.
RemoteName string | ||
// RefSpecs specify what destination ref to update with what source | ||
// object. A refspec with empty src can be used to delete a reference. | ||
RefSpecs []config.RefSpec |
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.
We can have a default RefSpec?
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.
yes: refs/heads/:refs/heads/. I've just added it. Note that git has different behaviours for default push refspec depending on config.
@@ -221,6 +376,27 @@ func getWants(spec []config.RefSpec, localStorer Storer, remoteRefs storer.Refer | |||
return result, nil | |||
} | |||
|
|||
func (r *Remote) referenceNeedsUpdate(wantTags bool, specs []config.RefSpec, |
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.
function not tested, or codecov failing
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 think it's not in use.
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.
removed, leftover from refactor
@@ -345,6 +345,20 @@ func (r *Repository) Fetch(o *FetchOptions) error { | |||
return remote.Fetch(o) | |||
} | |||
|
|||
// Push pushes changes to a remote. | |||
func (r *Repository) Push(o *PushOptions) error { |
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.
function not tested
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.
done.
* add Push method to Remote. * add method Push to Repository. * examples: add push example.
* remote: add Push. * add Push method to Remote. * add method Push to Repository. * examples: add push example. * requested changes * add tests, fixes
Uh oh!
There was an error while loading. Please reload this page.