`braid diff` silently ignores uncommitted changes
mattmccutchen opened this issue · 4 comments
braid diff
silently ignores uncommitted changes. It should at least give a warning or error, or better, include them in the diff.
(Going ahead and filing this, though I may be the one to implement it anyway.)
Some options for braid diff
with uncommitted changes, none of them perfect:
- Print an error and invite the user to run the command again with an
--ignore-uncommitted
option or so. - Print a warning. But the user might not notice the warning, especially if
git diff
invokes the pager and the warning is outside the paged output. - Set GIT_WORK_TREE to the mirror directory and run
git diff
against the upstream tree of the mirror.IgnoresAttributes in the repository configuration that refer to the mirror path won't be applied correctly; e.g., if.git/info/attributes
customizes the diff behavior for/skit1/my-notes.txt
but we useskit1
as the root for the diff, then git will look up the file path ofmy-notes.txt
and the attributes won't be used. [Edit: ignores don't affectgit diff
, but attributes may.] And unless we copy the relevant subtree of the real index file to a temporary index (which is more of a pain),git diff
will lose the performance benefit of skipping files that are unchanged compared to the index, and the--cached
option won't work. - Generate a base tree that has the upstream tree moved into the mirror directory (sort of like
braid update
does) and diff against that tree, limited to the mirror directory (so we don't need to load content outside the mirror directory like #42 changedbraid update
to do again). File paths in the diff output would include the mirror path; that's a change from the current behavior, though I personally don't find it any less reasonable than the current behavior. If the user passes their own path arguments to limit the diff, either we could require those arguments to already include the mirror path (e.g.,braid diff skit1 skit1/layouts/layout.liquid
) or we could prepend the mirror path automatically (e.g.,braid diff skit1 layouts/layout.liquid
->git diff BASE_TREE skit1/layouts/layout.liquid
).
I lean toward option 4. @realityforge, what do you think? Once we have a decision, I should be able to tackle #44 and #45 together.
Ok I guess the way we typically use it is as follows. Make changes in project that may include changes in vendored directory. Maybe at some later point diff the changes in vendored directory an apply upstream and then braid update. i.e.
$ braid add https://github.com/user/mytool.git vendor/tool/mytool
$ vi foo.rb vendor/tool/mytool/bar.rb vendor/tool/mytool/baz.rb
$ git commit -a -m "..."
...
$ braid diff vendor/tool/mytool > ../mytool/patch.diff
$ cd ../mytool && git apply patch.diff && git commit -a - m "..." && git push && cd ../myproject
$ braid update vendor/tool/mytool
The ability to diff uncommitted could be useful in some circumstances as it would avoid the need to commit to the project before doing a braid update. So I am reluctant to change anything that would break the above process which from the sounds of it (4) would do by requiring users to pass some additional params to git apply to strip off the path prefix? However from my basic understanding (2) and (3) do not seem ideal and (1) seems like a cop-out. If somehow (4) could be adapted so that the existing paths come through that would be ideal.
As to the syntax braid diff skit1 skit1/layouts/layout.liquid
versus braid diff skit1 layouts/layout.liquid
- I don't really have a strong opinion. The first allows easy completion while the second form would require completion scripts if you wanted tab expansion. I can not remember at this stage if I have completion scripts already and am away from my development machine so can't check but if I do we could always add them to the project if the second form is desired.
I re-read the git diff
man page and saw the --relative
option, which will let us omit the mirror path from the file paths in the output in method (4). Regardless of this option, git diff
will interpret its arguments relative to its working directory, so we can cd
to get a particular interpretation or just keep the user's original working directory. I like the second option since it gives the user the flexibility to write the paths either way without needing a custom completion script, but it raises some issues:
- None of the Braid commands correctly handles running in a subdirectory: they all look for
.braids
in the working directory. I'm willing to fix that. - Does it make sense to have the user to specify the full mirror path even when running Braid in a subdirectory? I'm leaning in favor.
Thoughts? Once we have the details decided, I can proceed to implementation.
Maybe at some later point diff the changes in vendored directory an apply upstream and then braid update.
I have some skepticism about whether we should encourage this workflow for sending changes back to the upstream project as opposed to something more automated that doesn't involve an intermediate patch, but for now it costs us nothing to continue supporting it. My use case for braid diff
is to review the total change I've made to a mirror as I'm working, and it's definitely useful to run that without committing.
--relative
sounds like it would work and I concur that the second option sounds good. Making braid handle working in a subdirectory sounds like a good idea. Hmm which reminds me - one thing that really annoys some users is that .braids
is not .braids.json
as their editors do not work with it. Maybe I can get around to fixing that one soonish - I will start adding some issues to tracker to start to record some of these issues.
WRT to (2) Using a full mirror path means you can't use auto completion and it would probably make more sense to use relative paths but it would be a little more work to get it working. However I am easy if it does not end up this way.
As to whether the intermediate patch is required. I think there are probably some better alternatives. I have never used braid push
but I expect that could be made to work, I could also see a new command like braid pull-request
being useful. However I guess we have to account for the facet that the same people may not have access to the upstream projects as those who are working on the downstream projects. At least for us that is true and thus why braid push
is unlikely to work. We typically sometimes require additional work before accepting the patch; sometimes minor tweaks, sometimes tests, sometimes testing to work in different environments (jruby versus mri ruby), different java versions etc. Anyhoo - something to keep in mind