1
0
Fork 0
mirror of https://github.com/git/git.git synced 2024-11-15 05:33:04 +01:00
Commit graph

39122 commits

Author SHA1 Message Date
Jeff King
da66b2743c remote.c: provide per-branch pushremote name
When remote.c loads its config, it records the
branch.*.pushremote for the current branch along with the
global remote.pushDefault value, and then binds them into a
single value: the default push for the current branch. We
then pass this value (which may be NULL) to remote_get_1
when looking up a remote for push.

This has a few downsides:

  1. It's confusing. The early-binding of the "current
     value" led to bugs like the one fixed by 98b406f
     (remote: handle pushremote config in any order,
     2014-02-24). And the fact that pushremotes fall back to
     ordinary remotes is not explicit at all; it happens
     because remote_get_1 cannot tell the difference between
     "we are not asking for the push remote" and "there is
     no push remote configured".

  2. It throws away intermediate data. After read_config()
     finishes, we have no idea what the value of
     remote.pushDefault was, because the string has been
     overwritten by the current branch's
     branch.*.pushremote.

  3. It doesn't record other data. We don't note the
     branch.*.pushremote value for anything but the current
     branch.

Let's make this more like the fetch-remote config. We'll
record the pushremote for each branch, and then explicitly
compute the correct remote for the current branch at the
time of reading.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2015-05-21 11:03:58 -07:00
Jeff King
f052154db3 remote.c: hoist branch.*.remote lookup out of remote_get_1
We'll want to use this logic as a fallback when looking up
the pushremote, so let's pull it out into its own function.

We don't technically need to make this available outside of
remote.c, but doing so will provide a consistent API with
pushremote_for_branch, which we will add later.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2015-05-21 11:03:49 -07:00
Jeff King
9e3751d443 remote.c: drop "remote" pointer from "struct branch"
When we create each branch struct, we fill in the
"remote_name" field from the config, and then fill in the
actual "remote" field (with a "struct remote") based on that
name. However, it turns out that nobody really cares about
the latter field. The only two sites that access it at all
are:

  1. git-merge, which uses it to notice when the branch does
     not have a remote defined. But we can easily replace this
     with looking at remote_name instead.

  2. remote.c itself, when setting up the @{upstream} merge
     config. But we don't need to save the "remote" in the
     "struct branch" for that; we can just look it up for
     the duration of the operation.

So there is no need to have both fields; they are redundant
with each other (the struct remote contains the name, or you
can look up the struct from the name). It would be nice to
simplify this, especially as we are going to add matching
pushremote config in a future patch (and it would be nice to
keep them consistent).

So which one do we keep and which one do we get rid of?

If we had a lot of callers accessing the struct, it would be
more efficient to keep it (since you have to do a lookup to
go from the name to the struct, but not vice versa). But we
don't have a lot of callers; we have exactly one, so
efficiency doesn't matter. We can decide this based on
simplicity and readability.

And the meaning of the struct value is somewhat unclear. Is
it always the remote matching remote_name? If remote_name is
NULL (i.e., no per-branch config), does the struct fall back
to the "origin" remote, or is it also NULL? These questions
will get even more tricky with pushremotes, whose fallback
behavior is more complicated. So let's just store the name,
which pretty clearly represents the branch.*.remote config.
Any lookup or fallback behavior can then be implemented in
helper functions.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2015-05-21 10:48:10 -07:00
Jeff King
ee2499fe38 remote.c: refactor setup of branch->merge list
When we call branch_get() to lookup or create a "struct
branch", we make sure the "merge" field is filled in so that
callers can access it. But the conditions under which we do
so are a little confusing, and can lead to two funny
situations:

  1. If there's no branch.*.remote config, we cannot provide
     branch->merge (because it is really just an application
     of branch.*.merge to our remote's refspecs). But
     branch->merge_nr may be non-zero, leading callers to be
     believe they can access branch->merge (e.g., in
     branch_merge_matches and elsewhere).

     It doesn't look like this can cause a segfault in
     practice, as most code paths dealing with merge config
     will bail early if there is no remote defined. But it's
     a bit of a dangerous construct.

     We can fix this by setting merge_nr to "0" explicitly
     when we realize that we have no merge config. Note that
     merge_nr also counts the "merge_name" fields (which we
     _do_ have; that's how merge_nr got incremented), so we
     will "lose" access to them, in the sense that we forget
     how many we had. But no callers actually care; we use
     merge_name only while iteratively reading the config,
     and then convert it to the final "merge" form the first
     time somebody calls branch_get().

  2. We set up the "merge" field every time branch_get is
     called, even if it has already been done. This leaks
     memory.

     It's not a big deal in practice, since most code paths
     will access only one branch, or perhaps each branch
     only one time. But if you want to be pathological, you
     can leak arbitrary memory with:

       yes @{upstream} | head -1000 | git rev-list --stdin

     We can fix this by skipping setup when branch->merge is
     already non-NULL.

In addition to those two fixes, this patch pushes the "do we
need to setup merge?" logic down into set_merge, where it is
a bit easier to follow.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2015-05-21 10:43:50 -07:00
Jeff King
e41bf352e3 remote.c: drop default_remote_name variable
When we read the remote config from disk, we update a
default_remote_name variable if we see branch.*.remote
config for the current branch. This isn't wrong, or even all
that complicated, but it is a bit simpler (because it
reduces our overall state) to just lazily compute the
default when we need it.

The ulterior motive here is that the push config uses a
similar structure, and _is_ much more complicated as a
result. That will be simplified in a future patch, and it's
more readable if the logic for remotes and push-remotes
matches.

Note that we also used default_remote_name as a signal that
the remote config has been loaded; after this patch, we now
use an explicit flag.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2015-05-03 11:42:28 -07:00
Junio C Hamano
2dfb2e07cb Git 2.4.0-rc0
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2015-03-26 11:59:05 -07:00
Junio C Hamano
30db51a3fe Merge branch 'jk/test-chain-lint'
People often forget to chain the commands in their test together
with &&, leaving a failure from an earlier command in the test go
unnoticed.  The new GIT_TEST_CHAIN_LINT mechanism allows you to
catch such a mistake more easily.

* jk/test-chain-lint: (36 commits)
  t9001: drop save_confirm helper
  t0020: use test_* helpers instead of hand-rolled messages
  t: simplify loop exit-code status variables
  t: fix some trivial cases of ignored exit codes in loops
  t7701: fix ignored exit code inside loop
  t3305: fix ignored exit code inside loop
  t0020: fix ignored exit code inside loops
  perf-lib: fix ignored exit code inside loop
  t6039: fix broken && chain
  t9158, t9161: fix broken &&-chain in git-svn tests
  t9104: fix test for following larger parents
  t4104: drop hand-rolled error reporting
  t0005: fix broken &&-chains
  t7004: fix embedded single-quotes
  t0050: appease --chain-lint
  t9001: use test_when_finished
  t4117: use modern test_* helpers
  t6034: use modern test_* helpers
  t1301: use modern test_* helpers
  t0020: use modern test_* helpers
  ...
2015-03-26 11:57:14 -07:00
Junio C Hamano
55a3b3c26e Merge branch 'sg/completion-gitcomp-nl-for-refs'
Code clean-up.

* sg/completion-gitcomp-nl-for-refs:
  completion: use __gitcomp_nl() for completing refs
2015-03-26 11:57:13 -07:00
Junio C Hamano
574ee8ae86 Merge branch 'jc/report-path-error-to-dir'
Code clean-up.

* jc/report-path-error-to-dir:
  report_path_error(): move to dir.c
2015-03-26 11:57:13 -07:00
Junio C Hamano
bca181109d Getting ready for -rc0
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2015-03-25 13:01:07 -07:00
Junio C Hamano
6ce3cc5d33 Merge branch 'nd/doc-git-index-version'
Doc clean-up.

* nd/doc-git-index-version:
  git.txt: list index versions in plain English
2015-03-25 12:54:28 -07:00
Junio C Hamano
ea1fd481b4 Merge branch 'jk/run-command-capture'
The run-command interface was easy to abuse and make a pipe for us
to read from the process, wait for the process to finish and then
attempt to read its output, which is a pattern that lead to a
deadlock.  Fix such uses by introducing a helper to do this
correctly (i.e. we need to read first and then wait the process to
finish) and also add code to prevent such abuse in the run-command
helper.

* jk/run-command-capture:
  run-command: forbid using run_command with piped output
  trailer: use capture_command
  submodule: use capture_command
  wt-status: use capture_command
  run-command: introduce capture_command helper
  wt_status: fix signedness mismatch in strbuf_read call
  wt-status: don't flush before running "submodule status"
2015-03-25 12:54:27 -07:00
Junio C Hamano
d78374e578 Merge branch 'tg/test-index-v4'
A test fix.

* tg/test-index-v4:
  t1700: make test pass with index-v4
2015-03-25 12:54:27 -07:00
Junio C Hamano
05e816e37f Merge branch 'jk/prune-with-corrupt-refs'
"git prune" used to largely ignore broken refs when deciding which
objects are still being used, which could spread an existing small
damage and make it a larger one.

* jk/prune-with-corrupt-refs:
  refs.c: drop curate_packed_refs
  repack: turn on "ref paranoia" when doing a destructive repack
  prune: turn on ref_paranoia flag
  refs: introduce a "ref paranoia" flag
  t5312: test object deletion code paths in a corrupted repository
2015-03-25 12:54:26 -07:00
Junio C Hamano
a801bb8c29 Merge branch 'tg/fix-check-order-with-split-index'
The split-index mode introduced at v2.3.0-rc0~41 was broken in the
codepath to protect us against a broken reimplementation of Git
that writes an invalid index with duplicated index entries, etc.

* tg/fix-check-order-with-split-index:
  read-cache: fix reading of split index
2015-03-25 12:54:26 -07:00
Junio C Hamano
2f6ef71387 Merge branch 'jk/fetch-pack'
"git fetch" that fetches a commit using the allow-tip-sha1-in-want
extension could have failed to fetch all the requested refs.

* jk/fetch-pack:
  fetch-pack: remove dead assignment to ref->new_sha1
  fetch_refs_via_pack: free extra copy of refs
  filter_ref: make a copy of extra "sought" entries
  filter_ref: avoid overwriting ref->old_sha1 with garbage
2015-03-25 12:54:25 -07:00
Junio C Hamano
927936d753 Merge branch 'jk/cleanup-failed-clone'
An failure early in the "git clone" that started creating the
working tree and repository could have resulted in some directories
and files left without getting cleaned up.

* jk/cleanup-failed-clone:
  clone: drop period from end of die_errno message
  clone: initialize atexit cleanup handler earlier
2015-03-25 12:54:24 -07:00
Junio C Hamano
cf07d3fe90 Merge branch 'jc/submitting-patches-mention-send-email'
Recommend format-patch and send-email for those who want to submit
patches to this project.

* jc/submitting-patches-mention-send-email:
  SubmittingPatches: encourage users to use format-patch and send-email
2015-03-25 12:54:23 -07:00
Junio C Hamano
dbd04eba01 Merge branch 'dj/log-graph-with-no-walk'
"git log --graph --no-walk A B..." is a otcnflicting request that
asks nonsense; no-walk tells us show discrete points in the
history, while graph asks to draw connections between these
discrete points. Forbid the combination.

* dj/log-graph-with-no-walk:
  revision: forbid combining --graph and --no-walk
2015-03-25 12:54:22 -07:00
Junio C Hamano
257b204f25 Merge branch 'kd/rev-list-bisect-first-parent'
"git rev-list --bisect --first-parent" does not work (yet) and can
even cause SEGV; forbid it.  "git log --bisect --first-parent"
would not be useful until "git bisect --first-parent" materializes,
so it is also forbidden for now.

* kd/rev-list-bisect-first-parent:
  rev-list: refuse --first-parent combined with --bisect
2015-03-25 12:54:21 -07:00
Junio C Hamano
01c057df3f Merge branch 'ws/grep-quiet-no-pager'
Even though "git grep --quiet" is run merely to ask for the exit
status, we spawned the pager regardless.  Stop doing that.

* ws/grep-quiet-no-pager:
  grep: fix "--quiet" overwriting current output
2015-03-25 12:54:20 -07:00
Junio C Hamano
09e32fa0f8 Merge branch 'jk/simplify-csum-file-sha1fd-check'
Code simplification.

* jk/simplify-csum-file-sha1fd-check:
  sha1fd_check: die when we cannot open the file
2015-03-25 12:54:19 -07:00
Junio C Hamano
5f15cba2f9 Merge branch 'ct/prompt-untracked-fix'
The prompt script (in contrib/) did not show the untracked sign
when working in a subdirectory without any untracked files.

* ct/prompt-untracked-fix:
  git prompt: use toplevel to find untracked files
2015-03-25 12:54:18 -07:00
Jeff King
fc99da1fb7 t9001: drop save_confirm helper
The idea of this helper is that we want to save the current
value of a config variable and then restore it again after
the test completes. However, there's no point in actually
saving the value; it should always be restored to the string
"never" (which you can confirm by instrumenting
save_confirm to print the value it finds).

Let's just replace it with a single test_when_finished call.

Suggested-by: SZEDER Gábor <szeder@ira.uka.de>
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2015-03-25 12:49:33 -07:00
Jeff King
be86fb3f8d t0020: use test_* helpers instead of hand-rolled messages
These tests are not wrong, but it is much shorter and more
idiomatic to say "verbose" or "test_must_fail" rather than
printing our own messages on failure. Likewise, there is no
need to say "happy" at the end of a test; the test suite
takes care of that.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2015-03-25 12:49:33 -07:00
Jeff King
c6587bddc4 t: simplify loop exit-code status variables
Since shell loops may drop the exit code of failed commands
inside the loop, some tests try to keep track of the status
by setting a variable. This can end up cumbersome and hard
to read; it is much simpler to just exit directly from the
loop using "return 1" (since each case is either in a helper
function or inside a test snippet).

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2015-03-25 12:49:33 -07:00
Jeff King
e6821d09e4 t: fix some trivial cases of ignored exit codes in loops
These are all cases where we do a setup step of the form:

  for i in $foo; do
	  set_up $i || break
  done &&
  more_setup

would not notice a failure in set_up (because break always
returns a 0 exit code). These are just setup steps that we
do not expect to fail, but it does not hurt to be defensive.

Most can be fixed by converting the "break" to a "return 1"
(since we eval our tests inside a function for just this
purpose). A few of the loops are inside subshells, so we can
use just "exit 1" to break out of the subshell. And a few
can actually be made shorter by just unrolling the loop.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2015-03-25 10:25:27 -07:00
Jeff King
76e057dba2 t7701: fix ignored exit code inside loop
When checking a list of file mtimes, we use a loop and break
out early from the loop if any entry does not match.
However, the exit code of a loop exited via break is always
0, meaning that the test will fail to notice we had a
mismatch. Since the loop is inside a function, we can fix
this by doing an early "return 1".

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2015-03-25 10:24:13 -07:00
Jeff King
6636cf7e90 t3305: fix ignored exit code inside loop
When we test deleting notes, we run "git notes remove" in a
loop. However, the exit value of the loop will only reflect
the final note we process. We should break out of the loop
with a failing exit code as soon as we see a problem.

Note that we can call "exit 1" here without explicitly
creating a subshell, because the while loop on the
right-hand side of a pipe executes in its own implicit
subshell.

Note also that the "break" above does not suffer the same
problem; it is meant to exit the loop early at a certain
number of iterations. We can bump it into the conditional of
the loop to make this more obvious.

Signed-off-by: Jeff King <peff@peff.net>
Acked-by: Johan Herland <johan@herland.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2015-03-25 10:23:58 -07:00
Jeff King
fd7771415b t0020: fix ignored exit code inside loops
A loop like:

  for f in one two; do
	  something $f ||
	  break
  done

will correctly break out of the loop when we see a failure
of one item, but the resulting exit code will always be
zero. We can fix that by putting the loop into a function or
subshell, but in this case it is simpler still to just
unroll the loop. We do add a helper function, which
hopefully makes the end result even more readable (in
addition to being shorter).

Reported-by: SZEDER Gábor <szeder@ira.uka.de>
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2015-03-25 10:22:35 -07:00
Jeff King
ecb590a9de perf-lib: fix ignored exit code inside loop
When copying the test repository, we try to detect whether
the copy succeeded. However, most of the heavy lifting is
done inside a for loop, where our "break" will lose the exit
code of the failing "cp". We can take advantage of the fact
that we are in a subshell, and just "exit 1" to break out
with a code.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2015-03-25 10:21:23 -07:00
Junio C Hamano
92e625d3a3 Merge branch 'master' of git://ozlabs.org/~paulus/gitk
* 'master' of git://ozlabs.org/~paulus/gitk:
  gitk: Update .po files
  gitk: l10n: Add Catalan translation
  gitk: Fix typo in Russian translation
  gitk: Remove tcl-format flag from a message that shouldn't have it
  gitk: Pass --invert-grep option down to "git log"
  gitk: Synchronize config file writes
  gitk: Report errors in saving config file
  gitk: Only write changed configuration variables
  gitk: Enable mouse horizontal scrolling in diff pane
  gitk: Default wrcomcmd to use --pretty=email
2015-03-24 16:10:37 -07:00
Junio C Hamano
777c55a616 report_path_error(): move to dir.c
The expected call sequence is for the caller to use match_pathspec()
repeatedly on a set of pathspecs, accumulating the "hits" in a
separate array, and then call this function to diagnose a pathspec
that never matched anything, as that can indicate a typo from the
command line, e.g. "git commit Maekfile".

Many builtin commands use this function from builtin/ls-files.c,
which is not a very healthy arrangement.  ls-files might have been
the first command to feel the need for such a helper, but the need
is shared by everybody who uses the "match and then report" pattern.

Move it to dir.c where match_pathspec() is defined.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
2015-03-24 14:12:10 -07:00
Nguyễn Thái Ngọc Duy
70320541ec git.txt: list index versions in plain English
At the first look, a user may think the default version is "23". Even
with UNIX background, there's no reference anywhere close that may
indicate this is glob or regex.

Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2015-03-24 08:06:00 -07:00
Junio C Hamano
f53fc38c08 Sync with v2.3.4 2015-03-23 11:37:49 -07:00
Junio C Hamano
9b22801c18 Post 2.3 cycle (batch #12)
Hopefully with another batch or two, we would be ready for -rc0
to close this cycle.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
2015-03-23 11:36:01 -07:00
Junio C Hamano
c267a4d013 Merge branch 'js/completion-ctags-pattern-substitution-fix'
The code that reads from the ctags file in the completion script
(in contrib/) did not spell ${param/pattern/string} substitution
correctly, which happened to work with bash but not with zsh.

* js/completion-ctags-pattern-substitution-fix:
  contrib/completion: escape the forward slash in __git_match_ctag
2015-03-23 11:28:16 -07:00
Junio C Hamano
61ca378275 Merge branch 'jk/push-config'
Restructure "git push" codepath to make it easier to add new
configuration bits and then add push.followTags configuration that
turns --follow-tags option on by default.

* jk/push-config:
  push: allow --follow-tags to be set by config push.followTags
  cmd_push: pass "flags" pointer to config callback
  cmd_push: set "atomic" bit directly
  git_push_config: drop cargo-culted wt_status pointer
2015-03-23 11:28:14 -07:00
Junio C Hamano
aa65b86025 Merge branch 'nd/config-doc-camelCase'
Documentation updates.

* nd/config-doc-camelCase:
  *config.txt: stick to camelCase naming convention
2015-03-23 11:28:12 -07:00
Junio C Hamano
07da4e092f Merge branch 'jk/test-annoyances'
Test fixes.

* jk/test-annoyances:
  t5551: make EXPENSIVE test cheaper
  t5541: move run_with_cmdline_limit to test-lib.sh
  t: pass GIT_TRACE through Apache
  t: redirect stderr GIT_TRACE to descriptor 4
  t: translate SIGINT to an exit
2015-03-23 11:28:10 -07:00
Junio C Hamano
c12eca7ed2 Merge branch 'jk/smart-http-hide-refs'
The transfer.hiderefs support did not quite work for smart-http
transport.

* jk/smart-http-hide-refs:
  upload-pack: do not check NULL return of lookup_unknown_object
  upload-pack: fix transfer.hiderefs over smart-http
2015-03-23 11:28:08 -07:00
Junio C Hamano
a633651d21 Merge branch 'jk/tag-h-column-is-a-listing-option'
"git tag -h" used to show the "--column" and "--sort" options
that are about listing in a wrong section.

* jk/tag-h-column-is-a-listing-option:
  tag: fix some mis-organized options in "-h" listing
2015-03-23 11:28:02 -07:00
Junio C Hamano
3a52578eef Git 2.3.4
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2015-03-23 11:27:27 -07:00
Junio C Hamano
437ed4cea1 Merge branch 'rs/use-isxdigit' into maint
Code cleanup.

* rs/use-isxdigit:
  use isxdigit() for checking if a character is a hexadecimal digit
2015-03-23 11:23:41 -07:00
Junio C Hamano
a393c6bfd9 Merge branch 'rs/deflate-init-cleanup' into maint
Code simplification.

* rs/deflate-init-cleanup:
  zlib: initialize git_zstream in git_deflate_init{,_gzip,_raw}
2015-03-23 11:23:38 -07:00
Junio C Hamano
a4f287e5aa Merge branch 'ak/git-done-help-cleanup' into maint
Code simplification.

* ak/git-done-help-cleanup:
  git: make was_alias and done_help non-static
2015-03-23 11:23:35 -07:00
Junio C Hamano
7d6f6e3730 Merge branch 'sg/completion-remote' into maint
Code simplification.

* sg/completion-remote:
  completion: simplify __git_remotes()
  completion: add a test for __git_remotes() helper function
2015-03-23 11:23:33 -07:00
Junio C Hamano
ffac6258de Merge branch 'mg/doc-status-color-slot' into maint
Documentation fixes.

* mg/doc-status-color-slot:
  config,completion: add color.status.unmerged
2015-03-23 11:23:31 -07:00
Junio C Hamano
3f6f5c9dbe Merge branch 'jc/decorate-leaky-separator-color' into maint
"git log --decorate" did not reset colors correctly around the
branch names.

* jc/decorate-leaky-separator-color:
  log --decorate: do not leak "commit" color into the next item
  Documentation/config.txt: simplify boolean description in the syntax section
  Documentation/config.txt: describe 'color' value type in the "Values" section
  Documentation/config.txt: have a separate "Values" section
  Documentation/config.txt: describe the structure first and then meaning
  Documentation/config.txt: explain multi-valued variables once
  Documentation/config.txt: avoid unnecessary negation
2015-03-23 11:23:28 -07:00
Junio C Hamano
c97418466a Merge branch 'kn/git-cd-to-empty' into maint
"git -C '' subcmd" refused to work in the current directory, unlike
"cd ''" which silently behaves as a no-op.

* kn/git-cd-to-empty:
  git: treat "git -C '<path>'" as a no-op when <path> is empty
2015-03-23 11:23:25 -07:00