-
Notifications
You must be signed in to change notification settings - Fork 534
new methods Worktree.[AddGlob|RemoveBlob] and recursive Worktree.[Add|Remove] #739
Conversation
Signed-off-by: Máximo Cuadros <[email protected]>
worktree_status.go
Outdated
// AddDirectory adds the files contents of a directory and all his | ||
// sub-directories recursively in the worktree to the index. If any of the | ||
// file is already staged in the index no error is returned. | ||
func (w *Worktree) AddDirectory(path string) 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.
This API seems a little clumsy to me. Is there a reason we can't simply detect and support directory paths as part of the current Add
function? A path string
is already sufficient for a user to describe either directories or files.
Moreover, if we are going to provide separate functions for directories on Add
we should also include separate functions MoveDirectory
and RemoveDirectory
for consistency.
In any case, I think we should simply extend the existing Add
, Move
, and Remove
to support directory paths.
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.
what should I return when I Add
a repository? Because the signature returns a 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.
It seems like Add
returns the hash of the blob object that was added to the repository. If one is adding a directory, it might make sense to return the hash of the corresponding tree object.
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.
Add
doesn't create any tree object.
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.
Ah yes. I see that. I guess this works then.
worktree_status.go
Outdated
// AddGlob given a glob pattern adds all the matching files content and all his | ||
// sub-directories recursively in the worktree to the index. If any of the | ||
// file is already staged in the index no error is returned. | ||
func (w *Worktree) AddGlob(pattern string) 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.
If we are going to support AddGlob
we should also add a RemoveGlob
for consistency in the API.
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.
Nice point.
@orirawlings PTAL |
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 is looking really good. :)
I just had a few minor suggestions and questions.
plumbing/format/index/index.go
Outdated
@@ -51,8 +53,20 @@ type Index struct { | |||
ResolveUndo *ResolveUndo | |||
} | |||
|
|||
// Add creates a new Entry and returns it. The caller should check that 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.
The caller should first check that another entry with the same path does not exist.
worktree_status.go
Outdated
// the worktree. | ||
ErrDestinationExists = errors.New("destination exists") | ||
// ErrGlobNoMatches in an AddGlob if the glob pattern does not match any | ||
// file in the worktree.ErrNotDirectory |
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.
Extra ErrNotDirectory
at end of this comment?
worktree_status.go
Outdated
ErrDestinationExists = errors.New("destination exists") | ||
// ErrGlobNoMatches in an AddGlob if the glob pattern does not match any | ||
// file in the worktree.ErrNotDirectory | ||
ErrGlobNoMatches = errors.New("glob pattern did not match any files") |
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.
match any paths
?
And maybe change the comment to refer to path instead of file as well?
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.
What match is files, so I thing is ok with files
worktree_status.go
Outdated
return | ||
} | ||
|
||
// AddGlob given a glob pattern adds all the matching files content and all his |
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.
Might be good to avoid the masculine pronoun, "his".
AddGlob adds all paths, matching pattern, to the index. If pattern matches a directory path, all directory contents are added to the index recursively. No error is returned if all matching paths are already staged in index.
worktree_status.go
Outdated
} | ||
return h, err | ||
|
||
return | ||
} | ||
|
||
if s.File(path).Worktree == Unmodified { |
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.
Would it be an optimization to move this check before the w.copyFileToStorage(path)
call?
worktree_status.go
Outdated
if err != nil { | ||
return plumbing.ZeroHash, err | ||
} | ||
|
||
if err := w.deleteFromFilesystem(path); 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.
Maybe just:
return hash, w.deleteFromFilesystem(path)
worktree_status.go
Outdated
@@ -409,6 +585,43 @@ func (w *Worktree) deleteFromFilesystem(path string) error { | |||
return err | |||
} | |||
|
|||
// RemoveGlob given a glob pattern removes all the matching files content and |
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 should probably avoid the masculine pronoun, "his", here too:
RemoveGlob removes all paths, matching pattern, from the index. If pattern matches a directory path, all directory contents are removed from the index recursively.
return err | ||
} | ||
|
||
if len(files) == 0 { |
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 curious here how we might use this method for a paths that might still exist in the repository or index, but might have already been removed from the working directory. Will this check cause this method to return an error without attempting to remove them from the index?
Example:
$ git init
$ touch a; git add a; git commit -m first
[master (root-commit) 5d36496] first
1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100644 a
$ rm a; git status
On branch master
Changes not staged for commit:
(use "git add/rm <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
deleted: a
no changes added to commit (use "git add" and/or "git commit -a")
$ git rm -- a*; git status
rm 'a'
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
deleted: a
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.
@mcuadros this seems like a bug to me. Can you confirm?
In git add
, you can modify entries in the index even if the glob matches no paths in the current working directory. But this check looks like it would return an error before trying to update the index if the glob has no matches in the working directory.
$ git init
$ touch a; git add a
$ rm a; ls a*
$ git add -- a*; echo $?
0
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 this is a very complex behavior, the goal of this PR was speed up multiple Add
calls.
|
||
return w.r.Storer.SetIndex(idx) | ||
} | ||
|
||
// Move moves or rename a file in the worktree and the index, directories are | ||
// not supported. | ||
func (w *Worktree) Move(from, to string) (plumbing.Hash, 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.
Are we planning to wait for now on adding support for directories to this method?
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.
Added TODO
Signed-off-by: Máximo Cuadros <[email protected]>
…|Remove] Signed-off-by: Máximo Cuadros <[email protected]>
@orirawlings PTAL |
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.
Sorry, I didn't have a look sooner.
Looks good. I just have one open question about using AddGlob
to remove files from the index. It looks to me like the current code doesn't support that, but git add -- <glob>
does.
return err | ||
} | ||
|
||
if len(files) == 0 { |
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.
@mcuadros this seems like a bug to me. Can you confirm?
In git add
, you can modify entries in the index even if the glob matches no paths in the current working directory. But this check looks like it would return an error before trying to update the index if the glob has no matches in the working directory.
$ git init
$ touch a; git add a
$ rm a; ls a*
$ git add -- a*; echo $?
0
} | ||
|
||
var saveIndex bool | ||
for _, file := range files { |
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 also looks like we aren't trying to match patterns on things in the index, only paths that exist in the working directory. This is slightly different behavior than git add -- <glob>
in cases where index entries should be removed (i.e. git add
supports both adding AND removing entries from the index).
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.
Add, only adds files from the woktree to the index. The function Add
should not do exactly the behavior of git add
. This is a programmatically interface, so I rather keep it simple.
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 that makes sense. I'm just anticipating that this discrepancy will cause confusion for users and drive more issues being opened.
Hi 😄 I looked a bit into billy's code and there is a Any ideas? |
Fixes: #456