From: Robin Rosenberg <robin.rosenberg.lists@dewire.com>
To: Jeff King <peff@peff.net>
Cc: Junio C Hamano <gitster@pobox.com>,
Anatol Pomozov <anatol.pomozov@gmail.com>,
git@vger.kernel.org,
Linus Torvalds <torvalds@linux-foundation.org>,
"Anatol Pomozov" <anatol.pomozov@gmail.com>
Subject: [PATCH] Make Git accept absolute path names for files within the work tree
Date: Mon, 3 Dec 2007 21:53:30 +0100 [thread overview]
Message-ID: <200712032153.31322.robin.rosenberg.lists@dewire.com> (raw)
In-Reply-To: <200712030755.37038.robin.rosenberg@dewire.com>
This patch makes it possible to drag files and directories from
a graphical browser and drop them onto a shell and feed them
to common git operations without editing away the path to the
root of the work tree.
Signed-off-by: Robin Rosenberg <robin.rosenberg@dewire.com>
---
I will not surrender to the fierce competion on this subject. Here is an update
with hopefully correct test cases this time. (Linus. your code did not pass). Like Linus,
this code does not resolve symlinks, but I forgot to state that it is by design. It
solves my problem and happens to solve Anatols problem (actually the same since
passing absolute file names to blame is my most important use case).
-- robin
builtin-blame.c | 4 +-
setup.c | 53 +++++++++++++++++++++++
t/t3904-abspatharg.sh | 112 +++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 166 insertions(+), 3 deletions(-)
create mode 100755 t/t3904-abspatharg.sh
diff --git a/builtin-blame.c b/builtin-blame.c
index c158d31..b905dcf 100644
--- a/builtin-blame.c
+++ b/builtin-blame.c
@@ -1880,9 +1880,7 @@ static unsigned parse_score(const char *arg)
static const char *add_prefix(const char *prefix, const char *path)
{
- if (!prefix || !prefix[0])
- return path;
- return prefix_path(prefix, strlen(prefix), path);
+ return prefix_path(prefix, prefix ? strlen(prefix) : 0, path);
}
/*
diff --git a/setup.c b/setup.c
index 2c7b5cb..1f0ec79 100644
--- a/setup.c
+++ b/setup.c
@@ -4,9 +4,62 @@
static int inside_git_dir = -1;
static int inside_work_tree = -1;
+static
+const char *strip_work_tree_path(const char *prefix, int len, const char *path)
+{
+ const char *work_tree = get_git_work_tree();
+ int n = strlen(work_tree);
+
+ if (strncmp(path, work_tree, n))
+ return path;
+
+ if (!prefix && !path[n])
+ return path + n;
+
+ if (!prefix) {
+ if (path[n] == '/')
+ return path + n + 1;
+ else
+ if (path[n])
+ return path;
+ else
+ return path + n;
+ }
+
+ if (prefix && !path[n])
+ return path;
+
+ if (strncmp(path + n + 1, prefix, len - 1)) {
+ fprintf(stderr,"prefix mismatch\n");
+ char *np;
+ int i;
+ int d=0;
+ for (i = 0; i < len; ++i)
+ if (prefix[i] == '/')
+ d++;
+ np = xmalloc(strlen(path + n) + d * 3 + 1);
+ for (i=0; i < d * 3; i += 3)
+ strcpy(np + i, "../");
+ strcpy(np + i, path + n + 1);
+ path = np;
+ return np;
+ }
+
+ if (path[len + n] == '/')
+ return path + len + n + 1;
+ else
+ if (path[len + n])
+ return path;
+ else
+ return path + len + n;
+}
+
const char *prefix_path(const char *prefix, int len, const char *path)
{
const char *orig = path;
+ if (is_absolute_path(path))
+ path = strip_work_tree_path(prefix, len, path);
+
for (;;) {
char c;
if (*path != '.')
diff --git a/t/t3904-abspatharg.sh b/t/t3904-abspatharg.sh
new file mode 100755
index 0000000..47f1222
--- /dev/null
+++ b/t/t3904-abspatharg.sh
@@ -0,0 +1,112 @@
+#!/bin/sh
+#
+# Copyright (C) 2007 Robin Rosenberg
+#
+
+test_description='Test absolute filename arguments to various git
+commands. Absolute arguments pointing to a location within the git
+work tree should behave the same as relative arguments. '
+
+. ./test-lib.sh
+
+test_expect_success 'add files using absolute path names' '
+ echo a >afile &&
+ echo b >bfile &&
+ git-add afile &&
+ git-add "$(pwd)/bfile" &&
+ test "afile bfile" = "$(echo $(git ls-files))"
+ mkdir x &&
+ (
+ cd x &&
+ echo c >cfile &&
+ echo d >dfile &&
+ git-add cfile &&
+ git-add "$(pwd)"
+ ) &&
+ test "afile bfile x/cfile x/dfile" = "$(echo $(git ls-files))" &&
+ git ls-files x >f1 &&
+ git ls-files "$(pwd)/x" >f2 &&
+ diff -u f1 f2
+'
+
+test_expect_success 'commit using absolute path names' '
+ git commit -m "foo" &&
+ echo aa >>bfile &&
+ git commit -m "aa" "$(pwd)/bfile"
+'
+
+test_expect_success 'log using absolute path names' '
+ echo bb >>bfile &&
+ git commit -m "bb" $(pwd)/bfile &&
+
+ git log bfile >f1.txt &&
+ git log "$(pwd)/bfile" >f2.txt &&
+ diff -u f1.txt f2.txt
+'
+
+test_expect_success 'blame using absolute path names' '
+ git blame bfile >f1.txt &&
+ git blame "$(pwd)/bfile" >f2.txt &&
+ diff -u f1.txt f2.txt
+'
+
+test_expect_success 'diff using absolute path names' '
+ git diff HEAD HEAD^ -- "$(pwd)/bfile" >f1.txt &&
+ git diff HEAD HEAD^ -- bfile >f2.txt &&
+ diff -u f1.txt f2.txt
+'
+
+test_expect_success 'rm using absolute path names' '
+ git rm "$(pwd)/afile" "$(pwd)/x/cfile" &&
+ test "bfile x/dfile" = "$(echo $(git ls-files))"
+'
+
+test_expect_success 'mv using absolute path names' '
+ git reset --hard &&
+ git mv "$(pwd)/afile" "$(pwd)/dfile" &&
+ test "bfile dfile x/cfile x/dfile" = "$(echo $(git ls-files))" &&
+ git mv "$(pwd)/dfile" afile &&
+ test "afile bfile x/cfile x/dfile" = "$(echo $(git ls-files))"
+'
+
+test_expect_success 'show using absolute path names' '
+ git reset --hard &&
+ git show "$(pwd)/bfile" >f1.txt &&
+ git show bfile >f2.txt &&
+ diff -u f1.txt f2.txt
+'
+
+test_expect_success 'add path in parent directory' '
+ (
+ d1="$(pwd)/x"
+ d2="$(pwd)/x/y"
+ mkdir -p x/y &&
+ echo hello1 >x/fa &&
+ echo hello2 >x/y/fb &&
+ cd x/y &&
+ git add "$d1/fa" "$d2/fb"
+ ) &&
+ test "afile bfile x/cfile x/dfile x/fa x/y/fb" = "$(echo $(git ls-files))"
+'
+
+test_expect_success 'add a parent directory' '
+ (
+ d1="$(pwd)/a"
+ d2="$(pwd)/a/b"
+ d3="$(pwd)/a/b/c"
+ mkdir -p a/b/c
+ echo helloa >a/a1 &&
+ echo hellob >a/b/b1 &&
+ echo helloc >a/b/c/c1 &&
+ cd a/b/c &&
+ git add "$d2"
+ ) &&
+ test "a/b/b1 a/b/c/c1 afile bfile x/cfile x/dfile x/fa x/y/fb" = "$(echo $(git ls-files))"
+'
+
+test_expect_failure 'add a directory outside the work tree' '
+ d1="(cd .. ; pwd)" &&
+ git add "$d1"
+'
+
+test_done
--
1.5.3.5.1.gb2df9
next prev parent reply other threads:[~2007-12-03 20:51 UTC|newest]
Thread overview: 31+ messages / expand[flat|nested] mbox.gz Atom feed top
2007-12-03 0:52 Incorrect git-blame result if I use full path to file Anatol Pomozov
2007-12-03 2:19 ` Junio C Hamano
2007-12-03 2:28 ` Jeff King
2007-12-03 17:26 ` Linus Torvalds
2007-12-03 18:09 ` Johannes Schindelin
2007-12-03 18:13 ` Linus Torvalds
2007-12-03 18:19 ` Linus Torvalds
2007-12-03 2:27 ` Jeff King
2007-12-03 2:40 ` Junio C Hamano
2007-12-03 2:49 ` Jeff King
2007-12-03 6:55 ` Robin Rosenberg
2007-12-03 20:53 ` Robin Rosenberg [this message]
2007-12-03 23:03 ` [PATCH] Make Git accept absolute path names for files within the work tree Junio C Hamano
2007-12-04 1:43 ` Jeff King
2007-12-04 2:17 ` Johannes Schindelin
2007-12-04 6:42 ` Robin Rosenberg
2007-12-04 11:50 ` Johannes Schindelin
2007-12-04 15:59 ` Linus Torvalds
2007-12-04 22:08 ` Jeff King
2007-12-04 22:52 ` Linus Torvalds
2007-12-06 6:12 ` Jeff King
-- strict thread matches above, loose matches on Subject: below --
2007-11-26 23:18 Robin Rosenberg
2007-11-27 0:24 ` Junio C Hamano
2007-11-27 23:20 ` Robin Rosenberg
2007-11-27 23:24 ` Robin Rosenberg
2007-11-28 8:43 ` Junio C Hamano
2007-11-29 1:15 ` Robin Rosenberg
2007-11-29 2:05 ` Junio C Hamano
2007-11-29 0:37 ` Junio C Hamano
2007-11-27 8:45 ` Johannes Sixt
2007-11-27 23:14 ` Robin Rosenberg
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=200712032153.31322.robin.rosenberg.lists@dewire.com \
--to=robin.rosenberg.lists@dewire.com \
--cc=anatol.pomozov@gmail.com \
--cc=git@vger.kernel.org \
--cc=gitster@pobox.com \
--cc=peff@peff.net \
--cc=torvalds@linux-foundation.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).