Thanks to visit codestin.com
Credit goes to github.com

Skip to content

reset: Allow the selective reset of pathspecs #1190

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

Merged
merged 6 commits into from
Feb 11, 2013
Merged

reset: Allow the selective reset of pathspecs #1190

merged 6 commits into from
Feb 11, 2013

Conversation

nulltoken
Copy link
Member

Not done yet. But I'd really like some early feedback on the API and proposed behavior

  • Initial implementation
  • Add some more tests (non existing path in Tree, conflicts removal, ...)
  • Add git-bash commands output above the tests
  • Gather feedback
  • Post review fixes

@nulltoken
Copy link
Member Author

/cc @jamill This should help pushing the repo.Index.Unstage() logic down into libgit2

@nulltoken
Copy link
Member Author

Hmm. Travis doesn't like this PR very much

I'm sorry but an error occured within Travis while running your build.

We are continuosly working on test run stability, please email [email protected] if this error persists.

Below is the stacktrace of the error:

Error: #<Travis::Worker::VirtualMachine::VmFatalError: The VM had trouble shutting down and has now been told off (forcefully killed), your build will be requeued shortly.>
  /home/travis/travis-worker/lib/travis/worker/virtual_machine/virtual_box.rb:203:in `close_sandbox'
  /home/travis/travis-worker/lib/travis/worker/virtual_machine/virtual_box.rb:200:in `close_sandbox'
  /home/travis/travis-worker/lib/travis/worker/virtual_machine/virtual_box.rb:129:in `sandboxed'
  /home/travis/travis-worker/vendor/bundle/jruby/1.9/bundler/gems/travis-build-486121f54bf2/lib/travis/build/remote.rb:25:in `perform'
  /home/travis/travis-worker/vendor/bundle/jruby/1.9/bundler/gems/travis-build-486121f54bf2/lib/travis/build.rb:52:in `run'
  org/jruby/RubyBasicObject.java:1659:in `__send__'
  org/jruby/RubyKernel.java:2086:in `send'
  /home/travis/travis-worker/vendor/bundle/jruby/1.9/bundler/gems/travis-support-e3e09d89fc8d/lib/travis/support/logging.rb:26:in `run_with_log'
  /home/travis/travis-worker/lib/travis/worker.rb:246:in `hard_timeout'
  /home/travis/travis-worker/lib/hard_timeout.rb:11:in `timeout'

@vmg
Copy link
Member

vmg commented Jan 16, 2013

The travis errors are not related to the PR. Let's try re-triggering the build...

@nulltoken
Copy link
Member Author

Rebased, force pushed and now Travis is happy!

break;
}

git_index_entry__free(entry);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Repeatedly allocating and freeing the git_index_entry here seems wasteful to me. Could this loop not read, instead:

for (i = 0; i < git_diff_num_deltas(diff); i++) {
    git_index_entry entry;

    if ((error = git_diff_get_patch(NULL, &delta, diff, i)) < 0)
        goto cleanup;

    memset(&entry, 0, sizeof(entry));
    entry->mode = delta->new_file.mode;
    entry->oid  = delta->new_file.oid;
    entry->path = delta->new_file.path;

    switch (delta->status) {
    ...
    }
}

Since the entry only has to exist for a moment in order to call git_index_add(), this would save two unnecessary alloc/frees per iteration of the loop. Additionally, if you were to do it this way, all the git_index_entry__free() exports could go away and the overall patch size would be reduced.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The actual code I wrote is not correct, btw. That needs to be entry.mode etc. when setting the values and the git_index_add() calls would need &entry, too.

@arrbee
Copy link
Member

arrbee commented Jan 18, 2013

So, I notice that the code path for git_reset() with GIT_RESET_DEFAULT is almost completely separate from the code path for every other value to git_reset(). This PR adds new checks around almost all of the error checking at the top that are conditional on this new value and then adds a completely separate function body that does a goto after calling the code that is unique to this particular value.

That makes me think that GIT_RESET_DEFAULT is actually a completely separate function. The error checks are different, the actions are different, and it even takes different inputs that are invalid with the other modes of operation for this function.

Would you consider adding a new API instead:

GIT_EXTERN(int) git_reset_default(
    git_repository *repo,
    git_object *target,
    git_strarray* pathspec);

where the target is optional, unlike a regular git_reset(), and the pathspec is allowed, and then leaving the existing git_reset() largely untouched?

I mostly ask this because it seems like the new option is functionally orthogonal to the old options and intermingling the two function bodies makes it harder to follow.

@nulltoken
Copy link
Member Author

@arrbee Thanks a lot for the review! I'll update the PR accordingly.

@nulltoken
Copy link
Member Author

@arrbee The PR has been fixed as requested.

}

opts.pathspec = *pathspecs;
opts.flags = GIT_DIFF_REVERSE;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For efficiency, you should probably add GIT_DIFF_SKIP_BINARY_CHECK here as well, otherwise when you call git_diff_get_patch() below, the diff code may actually load the files into memory so that it can set the binary flag correctly on the diff delta.

Alternatively, since this is internal to libgit2, you could just peek directly into the internal vector of git_diff_delta data inside the git_diff_list and not use git_diff_get_patch() for access.

@arrbee
Copy link
Member

arrbee commented Feb 4, 2013

Hey, so it appears to me that this code is creating two empty git_index objects and using them to store the entries to be removed and to be added. The two lists don't overlap and, at least for the deleted objects, I don't think we end up using anything other than the path to the object. Using a git_index as a list of object references like this is clever, but it seems like it might be heavier weight than needed. Maybe I'm overlooking something, but is there a reason why you can't just write:

size_t i;
git_diff_delta *delta;
git_index_entry entry = {0};

...

if ((error = git_diff_tree_to_index(&diff, repo, tree, index, &opts)) < 0)
    goto cleanup;

git_vector_foreach(&diff->deltas, i, delta) {
    if ((error = git_index_conflict_remove(index, delta->old_file.path)) < 0)
        goto cleanup;

    if (delta->status == GIT_DELTA_DELETED) {
        if ((error = git_index_remove(index, delta->old_file.path, 0)) < 0)
            goto cleanup;
    } else {
        entry.mode = delta->new_file.mode;
        git_oid_cpy(&entry.oid, &delta->new_file.oid);
        entry.path = (char *)delta->new_file.path;

        if ((error = git_index_add(to_be_included, &entry)) < 0)
            goto cleanup;
    }
}

...

Given the options being passed to diff, there should never be any records that are not deleted, added, or modified. You could probably add an assertion to that effect in the else clause if you were concerned about it.

I apologize if I've missed something and the indirection is needed!

@nulltoken
Copy link
Member Author

@arrbee The PR has been fixed according to your recommendations. Thanks to you the code is now shorter and clearer. Great lesson!

BTW, I've eventually memsetd the git_index_entry because Travis was complaining about the syntax.

224/home/travis/build/libgit2/libgit2/src/reset.c:69:27: warning: suggest braces around initialization of subobject [-Wmissing-braces]
225        git_index_entry entry = {0};
226                                 ^
227                                 {}

@arrbee
Copy link
Member

arrbee commented Feb 11, 2013

✨ Thanks!

arrbee added a commit that referenced this pull request Feb 11, 2013
reset: Allow the selective reset of pathspecs
@arrbee arrbee merged commit 390a3c8 into libgit2:development Feb 11, 2013
@nulltoken nulltoken deleted the topic/reset-paths branch February 14, 2013 21:02
phatblat pushed a commit to phatblat/libgit2 that referenced this pull request Sep 13, 2014
reset: Allow the selective reset of pathspecs
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

Successfully merging this pull request may close these issues.

3 participants