Skip to content

checkout: when examining index (instead of workdir), also examine mode#4535

Merged
pks-t merged 3 commits into
masterfrom
ethomson/checkout_typechange_with_index_and_wd
Feb 20, 2018
Merged

checkout: when examining index (instead of workdir), also examine mode#4535
pks-t merged 3 commits into
masterfrom
ethomson/checkout_typechange_with_index_and_wd

Conversation

@ethomson
Copy link
Copy Markdown
Member

When checking out a file, we determine whether the baseline (what we expect to be in the working directory) actually matches the contents of the working directory. This is safe behavior to prevent us from overwriting changes in the working directory.

We look at the index to optimize this test: if we know that the index matches the working directory, then we can simply look at the index data compared to the baseline.

We have historically compared the baseline to the index entry by oid. However, we must also compare the mode of the two items to ensure that they are identical. Otherwise, we will refuse to update the working directory for a mode change.

Update this behavior and include a test to validate the behavior.

@ethomson
Copy link
Copy Markdown
Member Author

This is a small and hopefully uncontroversial slice of #4536. I'm opening this separately only because it seems like a simple and obvious fix that we may want to include before the next release.

@pks-t
Copy link
Copy Markdown
Member

pks-t commented Feb 19, 2018

While this seems to work alright on Travis/AppVeyor, it causes "index::filemodes::frombuffer_requires_files" to fail for me:

  1) Failure:
index::filemodes::frombuffer_requires_files [/home/pks/Development/libgit2/tests/index/filemodes.c:276]
  Expression is not true: (ret_entry = git_index_get_bypath(index, "dummy-file.txt", 0))

@pks-t
Copy link
Copy Markdown
Member

pks-t commented Feb 19, 2018

Ugh, no. This is obviously because of #4529.

Copy link
Copy Markdown
Member

@pks-t pks-t left a comment

Choose a reason for hiding this comment

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

I think the change itself makes sense, I just have a few comments about the test

Comment thread tests/checkout/head.c Outdated
cl_must_pass(p_chmod("testrepo/new.txt", 0755));
cl_git_pass(git_repository_index(&index, g_repo));
cl_git_pass(git_index_add_bypath(index, "new.txt"));
git_index_write(index);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This line is missing an cl_git_pass.

Comment thread tests/checkout/head.c Outdated
cl_git_pass(git_repository_index(&index, g_repo));
cl_git_pass(git_index_add_bypath(index, "new.txt"));
git_index_write(index);
git_index_free(index);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I'd prefer to move that line to the end of the test

Comment thread tests/checkout/head.c
cl_git_pass(git_checkout_head(g_repo, &opts));

cl_git_pass(p_stat("testrepo/new.txt", &st));
cl_assert(!GIT_PERMS_IS_EXEC(st.st_mode));
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

As the second test is concerned about a different thing (index vs workdir), I'd move it into a separate test.

When checking out a file, we determine whether the baseline (what we
expect to be in the working directory) actually matches the contents
of the working directory.  This is safe behavior to prevent us from
overwriting changes in the working directory.

We look at the index to optimize this test: if we know that the index
matches the working directory, then we can simply look at the index
data compared to the baseline.

We have historically compared the baseline to the index entry by oid.
However, we must also compare the mode of the two items to ensure that
they are identical.  Otherwise, we will refuse to update the working
directory for a mode change.
@ethomson ethomson force-pushed the ethomson/checkout_typechange_with_index_and_wd branch from 3cf2996 to 755557e Compare February 19, 2018 22:12
@ethomson
Copy link
Copy Markdown
Member Author

I've fixed up the test per your requests.

Copy link
Copy Markdown
Member

@pks-t pks-t left a comment

Choose a reason for hiding this comment

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

Perfect, thanks a lot! One variable is leaking now, though. Do you want this change to be backported to v0.26.1?

Comment thread tests/checkout/head.c
void test_checkout_head__typechange_workdir(void)
{
git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
git_object *target;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This variable is leaking now

When the working directory has changed permissions on a file - but only
the permissions, such that the contents of the file are identical -
ensure that `git_checkout` updates the permissions to match the checkout
target.
When both the index _and_ the working directory has changed
permissions on a file permissions on a file - but only the permissions,
such that the contents of the file are identical - ensure that
`git_checkout` updates the permissions to match the checkout target.
@ethomson ethomson force-pushed the ethomson/checkout_typechange_with_index_and_wd branch from 755557e to 4e4771d Compare February 20, 2018 14:34
@ethomson
Copy link
Copy Markdown
Member Author

Agreed, I added the backport label.

@pks-t pks-t merged commit 894ccf4 into master Feb 20, 2018
@pks-t pks-t mentioned this pull request Feb 20, 2018
@ethomson ethomson deleted the ethomson/checkout_typechange_with_index_and_wd branch October 26, 2018 13:37
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.

2 participants