Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add a similarity-based postprocessor to interleave consecutive additions/deletions #17

Open
josharian opened this issue Dec 6, 2019 · 0 comments

Comments

@josharian
Copy link
Contributor

Consider this diff:

@@ -441,8 +441,26 @@ func (v *ReferenceNameIterator) Next() (string, error) {
        return C.GoString(ptr), nil
 }
 
-// Next retrieves the next reference. If the iterationis over, the
-// returned error is git.ErrIterOver
+// Slice returns a slice of all reference names.
+// It is a convenience function similar to calling Next repeatedly.
+// If Slice encounters an error, it returns all reference names up to that error.
+func (v *ReferenceNameIterator) Slice() ([]string, error) {
+       // TODO: implement directly in terms of git_reference_next_name?
+       var all []string
+       for {
+               s, err := v.Next()
+               if IsErrorCode(err, ErrIterOver) {
+                       return all, nil
+               }
+               if err != nil {
+                       return all, err
+               }
+               all = append(all, s)
+       }
+}
+
+// Next retrieves the next reference. If the iteration is over, the
+// returned error is git.ErrIterOver.
 func (v *ReferenceIterator) Next() (*Reference, error) {
        var ptr *C.git_reference

This diff would be greatly improved if it looked like this:

@@ -441,8 +441,26 @@ func (v *ReferenceNameIterator) Next() (string, error) {
        return C.GoString(ptr), nil
 }
 
+// Slice returns a slice of all reference names.
+// It is a convenience function similar to calling Next repeatedly.
+// If Slice encounters an error, it returns all reference names up to that error.
+func (v *ReferenceNameIterator) Slice() ([]string, error) {
+       // TODO: implement directly in terms of git_reference_next_name?
+       var all []string
+       for {
+               s, err := v.Next()
+               if IsErrorCode(err, ErrIterOver) {
+                       return all, nil
+               }
+               if err != nil {
+                       return all, err
+               }
+               all = append(all, s)
+       }
+}
+
-// Next retrieves the next reference. If the iterationis over, the
-// returned error is git.ErrIterOver
+// Next retrieves the next reference. If the iteration is over, the
+// returned error is git.ErrIterOver.
 func (v *ReferenceIterator) Next() (*Reference, error) {
        var ptr *C.git_reference

Not only it is clearer, it is likely to be far more helpful if you want to stage/patch part but not all of such a change.

Every diff algorithm generates the original diff (at least among diff algorithms implemented in git).

We could add an optional post-processing step that attempts to interleave additions and deletions based on the similarity of the content.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant