* Re: [PATCH] Highlight keyboard shortcuts in git-add--interactive
From: Dan Zwell @ 2007-11-21 23:00 UTC (permalink / raw)
To: Jeff King; +Cc: Wincent Colaiuta, Dan Zwell, git, gitster
In-Reply-To: <20071121152817.GA27144@sigill.intra.peff.net>
Jeff King wrote:
> Dan, any progress on the next revision of the patch
> series?
>
Yeah, I've been busy with school work, but Thanksgiving break has just
started. I hope to have something to send tonight, though it probably
will not be the final draft, as it has quite a bit of changes from the
last version.
Dan
^ permalink raw reply
* Re: [PATCH 2/4] Teach git-add--interactive to accept a file path to patch
From: Wincent Colaiuta @ 2007-11-21 22:44 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Jeff King, git
In-Reply-To: <7vejejfi28.fsf@gitster.siamese.dyndns.org>
El 21/11/2007, a las 21:40, Junio C Hamano escribió:
> Jeff King <peff@peff.net> writes:
>
>> ...
>> On top of that, it would be great to be able to do something like
>>
>> git-add -i *.c
>>
>> and just get prompted for changed files (right now, you only get
>> prompted for changed files, but unchanged files seem to print a
>> spurious
>> newline).
>>
>> And at any rate, this would require fixing 3/4 to handle the multiple
>> files from git-add.
>>
>> What do you think?
>
> If we are to add path limited behaviour, I think it should also
> grok "git-add -i sub/dir/". IOW, you would want to have the
> same path selection semantics as git-add without the
> "interactive" bit.
I can work on adding support for dirs as well as files, but am
wondering what the desired behaviour is:
- Jeff would like to pass "*.c" and have it only add changed files,
not unchanged or untracked files
- Junio, do you mean to suggest with your comment that when passing
untracked files either directly or indirectly (ie. when passing a dir
containing untracked files) that they should be added (ie. invoked the
"add untracked" subcommand) in addition to running the "patch"
subcommand on the changed files?
Of these two approaches, I suspect that the latter would be more
"correct", because it would be consistent with the "not interactive"
version of git-add.
Cheers,
Wincent
^ permalink raw reply
* Re: Git Screencast ?
From: Randal L. Schwartz @ 2007-11-21 22:36 UTC (permalink / raw)
To: Michael Donaghy; +Cc: git
In-Reply-To: <fi1a9f$30q$1@ger.gmane.org>
>>>>> "Michael" == Michael Donaghy <mike@mikedonaghy.org> writes:
Michael> I am a new user of git and SCMs in general , I have learned a lot
Michael> from the docs , irc and just using it , but there are just some
Michael> concepts that hare hard to grasp , I am a very visual persion
Michael> (probably like a lot of you :) ) , is there a screencast of git
Michael> somewhere (for free) that can demonstrate some of the advanced
Michael> features of git... (Also...I have seen both Randal (Schwartz) and
Michael> Linus' (you better know his last name) presentations at google on git
Michael> , in which they explain the ideas behind git more than the actual
Michael> usage,
Having been involved in that screencast that you reference, I'm curious
about what you think you're missing in order to use git. The feedback
will help me produce better presentations.
--
Randal L. Schwartz - Stonehenge Consulting Services, Inc. - +1 503 777 0095
<merlyn@stonehenge.com> <URL:http://www.stonehenge.com/merlyn/>
Perl/Unix/security consulting, Technical writing, Comedy, etc. etc.
See PerlTraining.Stonehenge.com for onsite and open-enrollment Perl training!
^ permalink raw reply
* Re: Adding push configuration to .git/config
From: Steffen Prohaska @ 2007-11-21 22:02 UTC (permalink / raw)
To: Nico -telmich- Schottelius; +Cc: git
In-Reply-To: <20071121105517.GA11875@denkbrett.schottelius.org>
On Nov 21, 2007, at 11:55 AM, Nico -telmich- Schottelius wrote:
> Hello guys!
>
> We are working pretty much with branches here and I think it would be
> pretty cool, to make git-push recognize some configuratio in
> ~/.git/config that describes where to push what:
>
> git-push origin master:<name of worker> is what we currenty do
> manually
>
> Nice would be
>
> [branch "master"]
> remote-push = origin
> remote-push-merge = another_branch
This was discussed in a similar form here:
http://marc.info/?l=git&m=119384331712996&w=2
http://marc.info/?l=git&m=119400354601328&w=2
So, yes, I think it would be very useful. I did not yet find
time to implement it.
> And thus perhaps also changing the existing specs:
>
> remote = ... to remote-fetch = ...
> merge = ... to remote-fetch-merge =
This is a logical consequence. It gives more freedom to pull
from one repo and push to another one.
I'm not fully convinced, though, of the configuration names
you propose. However, I have no better suggestion right away.
> And perhaps it would also make sense to replace "refs/heads/master"
> with
> only "master"?
No. We use full refnames everywhere. I think we should stick
with them.
Steffen
^ permalink raw reply
* Re: Git Screencast ?
From: Johan Herland @ 2007-11-21 21:51 UTC (permalink / raw)
To: Michael Donaghy; +Cc: git
In-Reply-To: <fi1a9f$30q$1@ger.gmane.org>
On Wednesday 21 November 2007, Michael Donaghy wrote:
> I am a new user of git and SCMs in general , I have learned a lot from
> the docs , irc and just using it , but there are just some concepts that
> hare hard to grasp , I am a very visual persion (probably like a lot of
> you :) ) , is there a screencast of git somewhere (for free) that can
> demonstrate some of the advanced features of git...
There's a company called PeepCode that apparently sell a Git screencast, but
I have no idea if it demonstrates advanced features, or just do the basics.
There seems to be a TOC on their website, so you can check that to see if
contains what you need:
http://peepcode.com/products/git
Have fun!
...Johan
--
Johan Herland, <johan@herland.net>
www.herland.net
^ permalink raw reply
* Re: Git in a Nutshell guide
From: Jakub Narebski @ 2007-11-21 21:32 UTC (permalink / raw)
To: Jan Hudec; +Cc: git
In-Reply-To: <20071121194507.GA3569@efreet.light.src>
Dnia środa 21. listopada 2007 20:45, Jan Hudec napisał:
> On Wed, Nov 21, 2007 at 00:57:28 +0100, Jakub Narebski wrote:
>> 2. Git has some historical cruft, including the fact that it began as
>> series of low level tools (plumbing) and became proper SCM (acquired
>> proper porcelain) later, what can be even now seen in documentation...
What I meant here that some of important documentation can be only
found in plumbing commands man pages.
>> 3. Explanation of some features (like object model) would be much easier
>> with some graphics (diagrams etc.), but chosen documentation format,
>> AsciiDoc, doesn't make it easy...
>
> I dare to disagree here. Asciidoc supports generating image tags for
> respective output formats and it really does not look hard. We could have
> PNGs and if we wanted higher press quality even SVG or EPS and convert them
> to PNGs for the HTML version (and use EPS for latex output).
The problem is that 1) language used to generate images must be easy
to understand and readable in text form (so sources are enough to
understand); 2) one of the main formats is manpage (although that would
not matter for "Git Guide" / "The Git Book").
Should we choose PIC? Or perhaps DOT? I can write little MetaPost, but
I don't think that would be good format for git diagrams, even if it
can be converted to PDF, SVG and PNG.
--
Jakub Narebski
Poland
^ permalink raw reply
* Re: [PATCH 2/4] Teach git-add--interactive to accept a file path to patch
From: Junio C Hamano @ 2007-11-21 20:40 UTC (permalink / raw)
To: Jeff King; +Cc: Wincent Colaiuta, git, gitster
In-Reply-To: <20071121152118.GG24108@sigill.intra.peff.net>
Jeff King <peff@peff.net> writes:
> ...
> On top of that, it would be great to be able to do something like
>
> git-add -i *.c
>
> and just get prompted for changed files (right now, you only get
> prompted for changed files, but unchanged files seem to print a spurious
> newline).
>
> And at any rate, this would require fixing 3/4 to handle the multiple
> files from git-add.
>
> What do you think?
If we are to add path limited behaviour, I think it should also
grok "git-add -i sub/dir/". IOW, you would want to have the
same path selection semantics as git-add without the
"interactive" bit.
^ permalink raw reply
* [PATCH 3/3] Replace setenv(GIT_DIR_ENVIRONMENT, ...) with set_git_dir()
From: Steffen Prohaska @ 2007-11-21 20:27 UTC (permalink / raw)
To: git; +Cc: Dmitry Kakurin, Steffen Prohaska
In-Reply-To: <11956768413887-git-send-email-prohaska@zib.de>
From: Dmitry Kakurin <Dmitry.Kakurin@gmail.com>
We have a function set_git_dir(). So let's use it, instead
of setting the evironment directly.
This also fixes a problem on Windows: environment.c caches
results of many getenv calls. A setenv(X) call to the Windows
C runtime (CRT) invalidates all previous values returned by
getenv(X). So cached values become dangling pointers.
Before this change, git clone was failing with 'invalid object
name HEAD' if ran from Windows' cmd.exe.
[sp: rebased; split off get_git_dir() in builtin-init-db.c
to separate commit; adjusted commit message. ]
Signed-off-by: Dmitry Kakurin <Dmitry.Kakurin@gmail.com>
Signed-off-by: Steffen Prohaska <prohaska@zib.de>
---
git.c | 6 +++---
path.c | 2 +-
setup.c | 2 +-
3 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/git.c b/git.c
index 7604319..8bc25b7 100644
--- a/git.c
+++ b/git.c
@@ -45,14 +45,14 @@ static int handle_options(const char*** argv, int* argc, int* envchanged)
fprintf(stderr, "No directory given for --git-dir.\n" );
usage(git_usage_string);
}
- setenv(GIT_DIR_ENVIRONMENT, (*argv)[1], 1);
+ set_git_dir( (*argv)[1] );
if (envchanged)
*envchanged = 1;
(*argv)++;
(*argc)--;
handled++;
} else if (!prefixcmp(cmd, "--git-dir=")) {
- setenv(GIT_DIR_ENVIRONMENT, cmd + 10, 1);
+ set_git_dir(cmd + 10);
if (envchanged)
*envchanged = 1;
} else if (!strcmp(cmd, "--work-tree")) {
@@ -72,7 +72,7 @@ static int handle_options(const char*** argv, int* argc, int* envchanged)
} else if (!strcmp(cmd, "--bare")) {
static char git_dir[PATH_MAX+1];
is_bare_repository_cfg = 1;
- setenv(GIT_DIR_ENVIRONMENT, getcwd(git_dir, sizeof(git_dir)), 0);
+ set_git_dir(getcwd(git_dir, sizeof(git_dir)));
if (envchanged)
*envchanged = 1;
} else {
diff --git a/path.c b/path.c
index 4260952..f26a4a1 100644
--- a/path.c
+++ b/path.c
@@ -248,7 +248,7 @@ char *enter_repo(char *path, int strict)
if (access("objects", X_OK) == 0 && access("refs", X_OK) == 0 &&
validate_headref("HEAD") == 0) {
- setenv(GIT_DIR_ENVIRONMENT, ".", 1);
+ set_git_dir(".");
check_repository_format();
return path;
}
diff --git a/setup.c b/setup.c
index 43cd3f9..8dbd46c 100644
--- a/setup.c
+++ b/setup.c
@@ -285,7 +285,7 @@ const char *setup_git_directory_gently(int *nongit_ok)
inside_git_dir = 1;
if (!work_tree_env)
inside_work_tree = 0;
- setenv(GIT_DIR_ENVIRONMENT, ".", 1);
+ set_git_dir(".");
return NULL;
}
chdir("..");
--
1.5.3.5.750.g8692
^ permalink raw reply related
* [PATCH 2/3] builtin-init-db: use get_git_dir() instead of getenv()
From: Steffen Prohaska @ 2007-11-21 20:27 UTC (permalink / raw)
To: git; +Cc: Steffen Prohaska
In-Reply-To: <11956768412804-git-send-email-prohaska@zib.de>
We have a function get_git_dir(). So let's use it,
instead of querying the environment.
Signed-off-by: Steffen Prohaska <prohaska@zib.de>
---
builtin-init-db.c | 4 +---
1 files changed, 1 insertions(+), 3 deletions(-)
diff --git a/builtin-init-db.c b/builtin-init-db.c
index 763fa55..80d2f27 100644
--- a/builtin-init-db.c
+++ b/builtin-init-db.c
@@ -378,9 +378,7 @@ int cmd_init_db(int argc, const char **argv, const char *prefix)
/*
* Set up the default .git directory contents
*/
- git_dir = getenv(GIT_DIR_ENVIRONMENT);
- if (!git_dir)
- git_dir = DEFAULT_GIT_DIR_ENVIRONMENT;
+ git_dir = get_git_dir();
safe_create_dir(git_dir, 0);
/* Check to see if the repository version is right.
--
1.5.3.5.750.g8692
^ permalink raw reply related
* [PATCH 0/3] msysgit fallout
From: Steffen Prohaska @ 2007-11-21 20:27 UTC (permalink / raw)
To: git
Here are three patches that come from msysgit. They do not bring
any functional changes, but only clean up code, or fix warnings.
Steffen
builtin-init-db.c | 4 +---
git.c | 6 +++---
path.c | 2 +-
setup.c | 2 +-
sha1_file.c | 10 ++++++----
5 files changed, 12 insertions(+), 12 deletions(-)
[PATCH 1/3] sha1_file.c: Fix size_t related printf format warnings
[PATCH 2/3] builtin-init-db: use get_git_dir() instead of getenv()
[PATCH 3/3] Replace setenv(GIT_DIR_ENVIRONMENT, ...) with set_git_dir()
^ permalink raw reply
* [PATCH 1/3] sha1_file.c: Fix size_t related printf format warnings
From: Steffen Prohaska @ 2007-11-21 20:27 UTC (permalink / raw)
To: git; +Cc: Steffen Prohaska
In-Reply-To: <11956768414090-git-send-email-prohaska@zib.de>
The old way of fixing warnings did not succeed on MinGW. MinGW
does not support C99 printf format strings for size_t [1]. But
gcc on MinGW issues warnings if C99 printf format is not used.
Hence, the old stragegy to avoid warnings fails.
[1] http://www.mingw.org/MinGWiki/index.php/C99
This commits passes arguments of type size_t through a tiny
helper functions that casts to the type expected by the format
string.
Signed-off-by: Steffen Prohaska <prohaska@zib.de>
---
sha1_file.c | 10 ++++++----
1 files changed, 6 insertions(+), 4 deletions(-)
diff --git a/sha1_file.c b/sha1_file.c
index f007874..4f68e53 100644
--- a/sha1_file.c
+++ b/sha1_file.c
@@ -25,8 +25,10 @@
#ifdef NO_C99_FORMAT
#define SZ_FMT "lu"
+static unsigned long sz_fmt(size_t s) { return (unsigned long)s; }
#else
#define SZ_FMT "zu"
+static size_t sz_fmt(size_t s) { return s; }
#endif
const unsigned char null_sha1[20];
@@ -423,9 +425,9 @@ void pack_report(void)
"pack_report: getpagesize() = %10" SZ_FMT "\n"
"pack_report: core.packedGitWindowSize = %10" SZ_FMT "\n"
"pack_report: core.packedGitLimit = %10" SZ_FMT "\n",
- (size_t) getpagesize(),
- packed_git_window_size,
- packed_git_limit);
+ sz_fmt(getpagesize()),
+ sz_fmt(packed_git_window_size),
+ sz_fmt(packed_git_limit));
fprintf(stderr,
"pack_report: pack_used_ctr = %10u\n"
"pack_report: pack_mmap_calls = %10u\n"
@@ -435,7 +437,7 @@ void pack_report(void)
pack_used_ctr,
pack_mmap_calls,
pack_open_windows, peak_pack_open_windows,
- pack_mapped, peak_pack_mapped);
+ sz_fmt(pack_mapped), sz_fmt(peak_pack_mapped));
}
static int check_packed_git_idx(const char *path, struct packed_git *p)
--
1.5.3.5.750.g8692
^ permalink raw reply related
* Re: Git Screencast ?
From: Johannes Gilger @ 2007-11-21 20:19 UTC (permalink / raw)
To: Michael Donaghy; +Cc: git
In-Reply-To: <fi1a9f$30q$1@ger.gmane.org>
On 21/11/07 08:02, Michael Donaghy wrote:
> I am a new user of git and SCMs in general , I have learned a lot from the
> docs , irc and just using it , but there are just some concepts that hare
> hard to grasp , I am a very visual persion (probably like a lot of you :) )
Hi Michael,
what helped me was
a) looking at the directory structure under .git
b) reading the git user-manual
c) http://eagain.net/articles/git-for-computer-scientists/
Especially c) created a big aha-effect. If you really read all the text
you should have understood most of it. And hey, since you're a visual
person: there are images too! ;)
Greetings,
Jojo
--
git version 1.5.3.6.861.gd794
^ permalink raw reply
* Re: gitweb: kernel versions in the history (feature request, probably)
From: Jarek Poplawski @ 2007-11-21 20:16 UTC (permalink / raw)
To: Petr Baudis; +Cc: J. Bruce Fields, linux-kernel, git
In-Reply-To: <20071121151831.GO1001@machine.or.cz>
Petr Baudis wrote, On 11/21/2007 04:18 PM:
> On Wed, Nov 21, 2007 at 08:52:17AM +0100, Jarek Poplawski wrote:
>> ...
>> tags
>> 4 days ago v2.6.24-rc3 Linux 2.6.24-rc3
>> 2 weeks ago v2.6.24-rc2 Linux 2.6.24-rc2
>> 4 weeks ago v2.6.24-rc1 Linux 2.6.24-rc1
>> 6 weeks ago v2.6.23 Linux 2.6.23
>>
>> which drives me crazy, because, without looking at the calendar, and
>> calculator, I don't really know which month was 6 weeks ago, and 4
>> days ago, either!
>
> I have myself never been sure if the relative times are a good idea or
> not. :-) Sometimes I hate them, sometimes they are more convenient...
>
> At any rate, if you click at the tag name, you should get tag page with
> full date.
So, it's so easy! Great! It seems I've to get used to this clicking
more. It seems I've become too cautious with this, when I've really
- really, waited after each click there. (I mean a few months ago,
and my connection was the same; sometimes, one such click took one
whole break for coffee.)
I seems, there are simply two kinds of people wrt. calendar/time. I'm
usually happy if I can figure by myself which day of week is today, but
I wouldn't even try with something like 4 days ago. But I understand
I'm not the brightest here...
So, maybe, some day, with: linux-kernel-for-dummies.org such things
could be reconsidered...
>
>> So, I go to the: http://www.eu.kernel.org/pub/linux/kernel/v2.6/,
>> do some scrolling, look at this:
>> ChangeLog-2.6.23 09-Oct-2007 20:38 3.8M
>>
>> and only now I can guess, this napi patch didn't manage to 2.6.23.
>> Of course, usually I've to do a few more clicks and reading to make
>> sure where it really started.
>>
>> So, this could suggest this 2007-10-10 (probably stored with time
>> too), could be useful here... but it seems, I'm wrong.
>
> Yes, there are three scenarios:
>
> (i) The patch has been _created_ after the release date. It can't be in
> the release.
> (ii) The patch has been created before the release date, but _committed_
> after the release date. It can't be in the release either.
> (iii) The patch has been committed before the release date. It _still_
> might not be in the release if it comes from a different branch.
> Imagine, say, tglx accepting the patch in his branch, then Linus
> releasing new kernel version, and only _then_ Linus merging tglx's
> branch.
>
> So the time information isn't really too useful if you want to be any
> sort of reliable.
>
>> Of course, this problem doesn't look so hard if we forget about
>> git internals: I can imagine keeping a simple database, which
>> could simply retrieve commit numbers from these ChangeLogs, and
>> connecting this with gitweb's commit page as well... For
>> performance reasons, doing it only for stable and testing, so with
>> -rc 'precision' would be very helpful too.
>
> It isn't too hard if we don't forget about git internals either. It's
> just that getting this information might not be cheap. But maybe I'm
> wrong and this won't be a problem for sane projects. Someone should post
> a patch. ;-)
It looks, after Kay's notice, my main problem is solved. And your current
explanations are also very precious to me. Probably some things considered
here could be done a bit better in the future, but I guess there is enough
urgent work with git or kernel too, so let's say it's OK for now!
Thanks every good git people!
Jarek P.
^ permalink raw reply
* [PATCH 2/3 v3] git-svn info: implement info command
From: David D. Kilzer @ 2007-11-21 19:57 UTC (permalink / raw)
To: Eric Wong; +Cc: git, David D. Kilzer
In-Reply-To: <1195675039-26746-2-git-send-email-ddkilzer@kilzer.net>
Implement "git-svn info" for files and directories based on the
"svn info" command. Note that the -r/--revision argument is not
supported yet.
Added 18 tests in t/t9119-git-svn-info.sh.
Signed-off-by: David D. Kilzer <ddkilzer@kilzer.net>
---
Documentation/git-svn.txt | 5 +
git-svn.perl | 132 ++++++++++++++++++++++
t/t9119-git-svn-info.sh | 274 +++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 411 insertions(+), 0 deletions(-)
create mode 100644 t/t9119-git-svn-info.sh
diff --git a/Documentation/git-svn.txt b/Documentation/git-svn.txt
index 488e4b1..c3fc878 100644
--- a/Documentation/git-svn.txt
+++ b/Documentation/git-svn.txt
@@ -193,6 +193,11 @@ Any other arguments are passed directly to `git log'
repository (that has been init-ed with git-svn).
The -r<revision> option is required for this.
+'info'::
+ Shows information about a file or directory similar to what
+ `svn info' provides. Does not currently support a -r/--revision
+ argument.
+
--
OPTIONS
diff --git a/git-svn.perl b/git-svn.perl
index 98c980f..be9290c 100755
--- a/git-svn.perl
+++ b/git-svn.perl
@@ -178,6 +178,10 @@ my %cmd = (
'file|F=s' => \$_file,
'revision|r=s' => \$_revision,
%cmt_opts } ],
+ 'info' => [ \&cmd_info,
+ "Show info about the latest SVN revision
+ on the current branch",
+ { } ],
);
my $cmd;
@@ -586,12 +590,18 @@ sub cmd_create_ignore {
sub canonicalize_path {
my ($path) = @_;
+ my $dot_slash_added = 0;
+ if (substr($path, 0, 1) ne "/") {
+ $path = "./" . $path;
+ $dot_slash_added = 1;
+ }
# File::Spec->canonpath doesn't collapse x/../y into y (for a
# good reason), so let's do this manually.
$path =~ s#/+#/#g;
$path =~ s#/\.(?:/|$)#/#g;
$path =~ s#/[^/]+/\.\.##g;
$path =~ s#/$##g;
+ $path =~ s#^\./## if $dot_slash_added;
return $path;
}
@@ -743,6 +753,104 @@ sub cmd_commit_diff {
}
}
+sub cmd_info {
+ my $path = canonicalize_path(shift or ".");
+ unless (scalar(@_) == 0) {
+ die "Too many arguments specified\n";
+ }
+
+ my ($file_type, $diff_status) = find_file_type_and_diff_status($path);
+
+ if (!$file_type && !$diff_status) {
+ print STDERR "$path: (Not a versioned resource)\n\n";
+ return;
+ }
+
+ my ($url, $rev, $uuid, $gs) = working_head_info('HEAD');
+ unless ($gs) {
+ die "Unable to determine upstream SVN information from ",
+ "working tree history\n";
+ }
+ my $full_url = $url . ($path eq "." ? "" : "/$path");
+
+ my $result = "Path: $path\n";
+ $result .= "Name: " . basename($path) . "\n" if $file_type ne "dir";
+ $result .= "URL: " . $full_url . "\n";
+
+ my $repos_root = $gs->ra->{repos_root};
+ Git::SVN::remove_username($repos_root);
+ $result .= "Repository Root: $repos_root\n";
+ $result .= "Repository UUID: $uuid\n" unless $diff_status eq "A";
+ $result .= "Revision: " . ($diff_status eq "A" ? 0 : $rev) . "\n";
+
+ $result .= "Node Kind: " .
+ ($file_type eq "dir" ? "directory" : "file") . "\n";
+
+ my $schedule = $diff_status eq "A"
+ ? "add"
+ : ($diff_status eq "D" ? "delete" : "normal");
+ $result .= "Schedule: $schedule\n";
+
+ if ($diff_status eq "A") {
+ print $result, "\n";
+ return;
+ }
+
+ my ($lc_author, $lc_rev, $lc_date_utc);
+ my @args = Git::SVN::Log::git_svn_log_cmd($rev, $rev, "--", $path);
+ my $log = command_output_pipe(@args);
+ my $esc_color = qr/(?:\033\[(?:(?:\d+;)*\d*)?m)*/;
+ while (<$log>) {
+ if (/^${esc_color}author (.+) <[^>]+> (\d+) ([\-\+]?\d+)$/o) {
+ $lc_author = $1;
+ $lc_date_utc = Git::SVN::Log::parse_git_date($2, $3);
+ } elsif (/^${esc_color} (git-svn-id:.+)$/o) {
+ (undef, $lc_rev, undef) = ::extract_metadata($1);
+ }
+ }
+ close $log;
+
+ Git::SVN::Log::set_local_timezone();
+
+ $result .= "Last Changed Author: $lc_author\n";
+ $result .= "Last Changed Rev: $lc_rev\n";
+ $result .= "Last Changed Date: " .
+ Git::SVN::Log::format_svn_date($lc_date_utc) . "\n";
+
+ if ($file_type ne "dir") {
+ my $text_last_updated_date =
+ ($diff_status eq "D" ? $lc_date_utc : (stat $path)[9]);
+ $result .=
+ "Text Last Updated: " .
+ Git::SVN::Log::format_svn_date($text_last_updated_date) .
+ "\n";
+ my $checksum;
+ if ($diff_status eq "D") {
+ my ($fh, $ctx) =
+ command_output_pipe(qw(cat-file blob), "HEAD:$path");
+ if ($file_type eq "link") {
+ my $file_name = <$fh>;
+ $checksum = Git::SVN::Util::md5sum("link $file_name");
+ } else {
+ $checksum = Git::SVN::Util::md5sum($fh);
+ }
+ command_close_pipe($fh, $ctx);
+ } elsif ($file_type eq "link") {
+ my $file_name =
+ command(qw(cat-file blob), "HEAD:$path");
+ $checksum =
+ Git::SVN::Util::md5sum("link " . $file_name);
+ } else {
+ open FILE, "<", $path or die $!;
+ $checksum = Git::SVN::Util::md5sum(\*FILE);
+ close FILE or die $!;
+ }
+ $result .= "Checksum: " . $checksum . "\n";
+ }
+
+ print $result, "\n";
+}
+
########################### utility functions #########################
sub rebase_cmd {
@@ -1050,6 +1158,30 @@ sub linearize_history {
(\@linear_refs, \%parents);
}
+sub find_file_type_and_diff_status {
+ my ($path) = @_;
+
+ my $diff_output =
+ command_oneline(qw(diff --cached --name-status --), $path) || "";
+ my $diff_status = (split(' ', $diff_output))[0] || "";
+
+ my $ls_tree = command_oneline(qw(ls-tree HEAD), $path) || "";
+
+ return (undef, undef) if !$diff_status && !$ls_tree;
+
+ if ($diff_status eq "A") {
+ return ("link", $diff_status) if -l $path;
+ return ("dir", $diff_status) if -d $path;
+ return ("file", $diff_status);
+ }
+
+ my $mode = (split(' ', $ls_tree))[0] || "";
+
+ return ("link", $diff_status) if $mode eq "120000";
+ return ("dir", $diff_status) if $mode eq "040000";
+ return ("file", $diff_status);
+}
+
package Git::SVN::Util;
use strict;
use warnings;
diff --git a/t/t9119-git-svn-info.sh b/t/t9119-git-svn-info.sh
new file mode 100644
index 0000000..edd64d6
--- /dev/null
+++ b/t/t9119-git-svn-info.sh
@@ -0,0 +1,274 @@
+#!/bin/sh
+#
+# Copyright (c) 2007 David D. Kilzer
+
+test_description='git-svn info'
+
+. ./lib-git-svn.sh
+
+ptouch() {
+ perl -w -e '
+ use strict;
+ die "ptouch requires exactly 2 arguments" if @ARGV != 2;
+ die "$ARGV[0] does not exist" if ! -e $ARGV[0];
+ my @s = stat $ARGV[0];
+ utime $s[8], $s[9], $ARGV[1];
+ ' "$1" "$2"
+}
+
+test_expect_success 'setup repository and import' "
+ mkdir info &&
+ cd info &&
+ echo one > file &&
+ ln -s file symlink-file &&
+ mkdir directory &&
+ touch directory/.placeholder &&
+ ln -s directory symlink-directory &&
+ svn import -m 'initial' . $svnrepo &&
+ cd .. &&
+ mkdir gitwc &&
+ cd gitwc &&
+ git-svn init $svnrepo &&
+ git-svn fetch &&
+ cd .. &&
+ svn co $svnrepo svnwc &&
+ ptouch svnwc/file gitwc/file &&
+ ptouch svnwc/directory gitwc/directory &&
+ ptouch svnwc/symlink-file gitwc/symlink-file &&
+ ptouch svnwc/symlink-directory gitwc/symlink-directory
+ "
+
+test_expect_success 'info' "
+ (cd svnwc; svn info) > expected.info &&
+ (cd gitwc; git-svn info) > actual.info &&
+ git-diff expected.info actual.info
+ "
+
+test_expect_success 'info .' "
+ (cd svnwc; svn info .) > expected.info-dot &&
+ (cd gitwc; git-svn info .) > actual.info-dot &&
+ git-diff expected.info-dot actual.info-dot
+ "
+
+test_expect_success 'info file' "
+ (cd svnwc; svn info file) > expected.info-file &&
+ (cd gitwc; git-svn info file) > actual.info-file &&
+ git-diff expected.info-file actual.info-file
+ "
+
+test_expect_success 'info directory' "
+ (cd svnwc; svn info directory) > expected.info-directory &&
+ (cd gitwc; git-svn info directory) > actual.info-directory &&
+ git-diff expected.info-directory actual.info-directory
+ "
+
+test_expect_success 'info symlink-file' "
+ (cd svnwc; svn info symlink-file) > expected.info-symlink-file &&
+ (cd gitwc; git-svn info symlink-file) > actual.info-symlink-file &&
+ git-diff expected.info-symlink-file actual.info-symlink-file
+ "
+
+test_expect_success 'info symlink-directory' "
+ (cd svnwc; svn info symlink-directory) \
+ > expected.info-symlink-directory &&
+ (cd gitwc; git-svn info symlink-directory) \
+ > actual.info-symlink-directory &&
+ git-diff expected.info-symlink-directory actual.info-symlink-directory
+ "
+
+test_expect_success 'info added-file' "
+ echo two > gitwc/added-file &&
+ cd gitwc &&
+ git add added-file &&
+ cd .. &&
+ cp gitwc/added-file svnwc/added-file &&
+ ptouch gitwc/added-file svnwc/added-file &&
+ cd svnwc &&
+ svn add added-file > /dev/null &&
+ cd .. &&
+ (cd svnwc; svn info added-file) > expected.info-added-file &&
+ (cd gitwc; git-svn info added-file) > actual.info-added-file &&
+ git-diff expected.info-added-file actual.info-added-file
+ "
+
+test_expect_success 'info added-directory' "
+ mkdir gitwc/added-directory svnwc/added-directory &&
+ ptouch gitwc/added-directory svnwc/added-directory &&
+ touch gitwc/added-directory/.placeholder &&
+ cd svnwc &&
+ svn add added-directory > /dev/null &&
+ cd .. &&
+ cd gitwc &&
+ git add added-directory &&
+ cd .. &&
+ (cd svnwc; svn info added-directory) \
+ > expected.info-added-directory &&
+ (cd gitwc; git-svn info added-directory) \
+ > actual.info-added-directory &&
+ git-diff expected.info-added-directory actual.info-added-directory
+ "
+
+test_expect_success 'info added-symlink-file' "
+ cd gitwc &&
+ ln -s added-file added-symlink-file &&
+ git add added-symlink-file &&
+ cd .. &&
+ cd svnwc &&
+ ln -s added-file added-symlink-file &&
+ svn add added-symlink-file > /dev/null &&
+ cd .. &&
+ ptouch gitwc/added-symlink-file svnwc/added-symlink-file &&
+ (cd svnwc; svn info added-symlink-file) \
+ > expected.info-added-symlink-file &&
+ (cd gitwc; git-svn info added-symlink-file) \
+ > actual.info-added-symlink-file &&
+ git-diff expected.info-added-symlink-file \
+ actual.info-added-symlink-file
+ "
+
+test_expect_success 'info added-symlink-directory' "
+ cd gitwc &&
+ ln -s added-directory added-symlink-directory &&
+ git add added-symlink-directory &&
+ cd .. &&
+ cd svnwc &&
+ ln -s added-directory added-symlink-directory &&
+ svn add added-symlink-directory > /dev/null &&
+ cd .. &&
+ ptouch gitwc/added-symlink-directory svnwc/added-symlink-directory &&
+ (cd svnwc; svn info added-symlink-directory) \
+ > expected.info-added-symlink-directory &&
+ (cd gitwc; git-svn info added-symlink-directory) \
+ > actual.info-added-symlink-directory &&
+ git-diff expected.info-added-symlink-directory \
+ actual.info-added-symlink-directory
+ "
+
+# The next few tests replace the "Text Last Updated" value with a
+# placeholder since git doesn't have a way to know the date that a
+# now-deleted file was last checked out locally. Internally it
+# simply reuses the Last Changed Date.
+
+test_expect_success 'info deleted-file' "
+ cd gitwc &&
+ git rm -f file > /dev/null &&
+ cd .. &&
+ cd svnwc &&
+ svn rm --force file > /dev/null &&
+ cd .. &&
+ (cd svnwc; svn info file) |
+ sed -e 's/^\(Text Last Updated:\).*/\1 TEXT-LAST-UPDATED-STRING/' \
+ > expected.info-deleted-file &&
+ (cd gitwc; git-svn info file) |
+ sed -e 's/^\(Text Last Updated:\).*/\1 TEXT-LAST-UPDATED-STRING/' \
+ > actual.info-deleted-file &&
+ git-diff expected.info-deleted-file actual.info-deleted-file
+ "
+
+test_expect_success 'info deleted-directory' "
+ cd gitwc &&
+ git rm -r -f directory > /dev/null &&
+ cd .. &&
+ cd svnwc &&
+ svn rm --force directory > /dev/null &&
+ cd .. &&
+ (cd svnwc; svn info directory) |
+ sed -e 's/^\(Text Last Updated:\).*/\1 TEXT-LAST-UPDATED-STRING/' \
+ > expected.info-deleted-directory &&
+ (cd gitwc; git-svn info directory) |
+ sed -e 's/^\(Text Last Updated:\).*/\1 TEXT-LAST-UPDATED-STRING/' \
+ > actual.info-deleted-directory &&
+ git-diff expected.info-deleted-directory actual.info-deleted-directory
+ "
+
+test_expect_success 'info deleted-symlink-file' "
+ cd gitwc &&
+ git rm -f symlink-file > /dev/null &&
+ cd .. &&
+ cd svnwc &&
+ svn rm --force symlink-file > /dev/null &&
+ cd .. &&
+ (cd svnwc; svn info symlink-file) |
+ sed -e 's/^\(Text Last Updated:\).*/\1 TEXT-LAST-UPDATED-STRING/' \
+ > expected.info-deleted-symlink-file &&
+ (cd gitwc; git-svn info symlink-file) |
+ sed -e 's/^\(Text Last Updated:\).*/\1 TEXT-LAST-UPDATED-STRING/' \
+ > actual.info-deleted-symlink-file &&
+ git-diff expected.info-deleted-symlink-file \
+ actual.info-deleted-symlink-file
+ "
+
+test_expect_success 'info deleted-symlink-directory' "
+ cd gitwc &&
+ git rm -f symlink-directory > /dev/null &&
+ cd .. &&
+ cd svnwc &&
+ svn rm --force symlink-directory > /dev/null &&
+ cd .. &&
+ (cd svnwc; svn info symlink-directory) |
+ sed -e 's/^\(Text Last Updated:\).*/\1 TEXT-LAST-UPDATED-STRING/' \
+ > expected.info-deleted-symlink-directory &&
+ (cd gitwc; git-svn info symlink-directory) |
+ sed -e 's/^\(Text Last Updated:\).*/\1 TEXT-LAST-UPDATED-STRING/' \
+ > actual.info-deleted-symlink-directory &&
+ git-diff expected.info-deleted-symlink-directory \
+ actual.info-deleted-symlink-directory
+ "
+
+# NOTE: git does not have the concept of replaced objects,
+# so we can't test for files in that state.
+
+test_expect_success 'info unknown-file' "
+ echo two > gitwc/unknown-file &&
+ cp gitwc/unknown-file svnwc/unknown-file &&
+ ptouch gitwc/unknown-file svnwc/unknown-file &&
+ (cd svnwc; svn info unknown-file) 2> expected.info-unknown-file &&
+ (cd gitwc; git-svn info unknown-file) 2> actual.info-unknown-file &&
+ git-diff expected.info-unknown-file actual.info-unknown-file
+ "
+
+test_expect_success 'info unknown-directory' "
+ mkdir gitwc/unknown-directory svnwc/unknown-directory &&
+ ptouch gitwc/unknown-directory svnwc/unknown-directory &&
+ touch gitwc/unknown-directory/.placeholder &&
+ (cd svnwc; svn info unknown-directory) \
+ 2> expected.info-unknown-directory &&
+ (cd gitwc; git-svn info unknown-directory) \
+ 2> actual.info-unknown-directory &&
+ git-diff expected.info-unknown-directory actual.info-unknown-directory
+ "
+
+test_expect_success 'info unknown-symlink-file' "
+ cd gitwc &&
+ ln -s unknown-file unknown-symlink-file &&
+ cd .. &&
+ cd svnwc &&
+ ln -s unknown-file unknown-symlink-file &&
+ cd .. &&
+ ptouch gitwc/unknown-symlink-file svnwc/unknown-symlink-file &&
+ (cd svnwc; svn info unknown-symlink-file) \
+ 2> expected.info-unknown-symlink-file &&
+ (cd gitwc; git-svn info unknown-symlink-file) \
+ 2> actual.info-unknown-symlink-file &&
+ git-diff expected.info-unknown-symlink-file \
+ actual.info-unknown-symlink-file
+ "
+
+test_expect_success 'info unknown-symlink-directory' "
+ cd gitwc &&
+ ln -s unknown-directory unknown-symlink-directory &&
+ cd .. &&
+ cd svnwc &&
+ ln -s unknown-directory unknown-symlink-directory &&
+ cd .. &&
+ ptouch gitwc/unknown-symlink-directory \
+ svnwc/unknown-symlink-directory &&
+ (cd svnwc; svn info unknown-symlink-directory) \
+ 2> expected.info-unknown-symlink-directory &&
+ (cd gitwc; git-svn info unknown-symlink-directory) \
+ 2> actual.info-unknown-symlink-directory &&
+ git-diff expected.info-unknown-symlink-directory \
+ actual.info-unknown-symlink-directory
+ "
+
+test_done
--
1.5.3.4
^ permalink raw reply related
* [PATCH 3/3 v3] git-svn: info --url [path]
From: David D. Kilzer @ 2007-11-21 19:57 UTC (permalink / raw)
To: Eric Wong; +Cc: git, David D. Kilzer
In-Reply-To: <1195675039-26746-3-git-send-email-ddkilzer@kilzer.net>
Return the svn URL for the given path, or return the svn
repository URL if no path is given.
Added 18 tests to t/t9119-git-svn-info.sh.
Signed-off-by: David D. Kilzer <ddkilzer@kilzer.net>
---
Documentation/git-svn.txt | 3 +-
git-svn.perl | 9 +++-
t/t9119-git-svn-info.sh | 93 +++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 102 insertions(+), 3 deletions(-)
diff --git a/Documentation/git-svn.txt b/Documentation/git-svn.txt
index c3fc878..918a992 100644
--- a/Documentation/git-svn.txt
+++ b/Documentation/git-svn.txt
@@ -196,7 +196,8 @@ Any other arguments are passed directly to `git log'
'info'::
Shows information about a file or directory similar to what
`svn info' provides. Does not currently support a -r/--revision
- argument.
+ argument. Use the --url option to output only the value of the
+ 'URL:' field.
--
diff --git a/git-svn.perl b/git-svn.perl
index be9290c..62801c8 100755
--- a/git-svn.perl
+++ b/git-svn.perl
@@ -65,7 +65,7 @@ my ($_stdin, $_help, $_edit,
$_template, $_shared,
$_version, $_fetch_all, $_no_rebase,
$_merge, $_strategy, $_dry_run, $_local,
- $_prefix, $_no_checkout, $_verbose);
+ $_prefix, $_no_checkout, $_url, $_verbose);
$Git::SVN::_follow_parent = 1;
my %remote_opts = ( 'username=s' => \$Git::SVN::Prompt::_username,
'config-dir=s' => \$Git::SVN::Ra::config_dir,
@@ -181,7 +181,7 @@ my %cmd = (
'info' => [ \&cmd_info,
"Show info about the latest SVN revision
on the current branch",
- { } ],
+ { 'url' => \$_url, } ],
);
my $cmd;
@@ -773,6 +773,11 @@ sub cmd_info {
}
my $full_url = $url . ($path eq "." ? "" : "/$path");
+ if ($_url) {
+ print $full_url, "\n";
+ return;
+ }
+
my $result = "Path: $path\n";
$result .= "Name: " . basename($path) . "\n" if $file_type ne "dir";
$result .= "URL: " . $full_url . "\n";
diff --git a/t/t9119-git-svn-info.sh b/t/t9119-git-svn-info.sh
index edd64d6..e81457f 100644
--- a/t/t9119-git-svn-info.sh
+++ b/t/t9119-git-svn-info.sh
@@ -44,30 +44,51 @@ test_expect_success 'info' "
git-diff expected.info actual.info
"
+test_expect_success 'info --url' '
+ test $(cd gitwc; git-svn info --url) = $svnrepo
+ '
+
test_expect_success 'info .' "
(cd svnwc; svn info .) > expected.info-dot &&
(cd gitwc; git-svn info .) > actual.info-dot &&
git-diff expected.info-dot actual.info-dot
"
+test_expect_success 'info --url .' '
+ test $(cd gitwc; git-svn info --url .) = $svnrepo
+ '
+
test_expect_success 'info file' "
(cd svnwc; svn info file) > expected.info-file &&
(cd gitwc; git-svn info file) > actual.info-file &&
git-diff expected.info-file actual.info-file
"
+test_expect_success 'info --url file' '
+ test $(cd gitwc; git-svn info --url file) = "$svnrepo/file"
+ '
+
test_expect_success 'info directory' "
(cd svnwc; svn info directory) > expected.info-directory &&
(cd gitwc; git-svn info directory) > actual.info-directory &&
git-diff expected.info-directory actual.info-directory
"
+test_expect_success 'info --url directory' '
+ test $(cd gitwc; git-svn info --url directory) = "$svnrepo/directory"
+ '
+
test_expect_success 'info symlink-file' "
(cd svnwc; svn info symlink-file) > expected.info-symlink-file &&
(cd gitwc; git-svn info symlink-file) > actual.info-symlink-file &&
git-diff expected.info-symlink-file actual.info-symlink-file
"
+test_expect_success 'info --url symlink-file' '
+ test $(cd gitwc; git-svn info --url symlink-file) \
+ = "$svnrepo/symlink-file"
+ '
+
test_expect_success 'info symlink-directory' "
(cd svnwc; svn info symlink-directory) \
> expected.info-symlink-directory &&
@@ -76,6 +97,11 @@ test_expect_success 'info symlink-directory' "
git-diff expected.info-symlink-directory actual.info-symlink-directory
"
+test_expect_success 'info --url symlink-directory' '
+ test $(cd gitwc; git-svn info --url symlink-directory) \
+ = "$svnrepo/symlink-directory"
+ '
+
test_expect_success 'info added-file' "
echo two > gitwc/added-file &&
cd gitwc &&
@@ -91,6 +117,11 @@ test_expect_success 'info added-file' "
git-diff expected.info-added-file actual.info-added-file
"
+test_expect_success 'info --url added-file' '
+ test $(cd gitwc; git-svn info --url added-file) \
+ = "$svnrepo/added-file"
+ '
+
test_expect_success 'info added-directory' "
mkdir gitwc/added-directory svnwc/added-directory &&
ptouch gitwc/added-directory svnwc/added-directory &&
@@ -108,6 +139,11 @@ test_expect_success 'info added-directory' "
git-diff expected.info-added-directory actual.info-added-directory
"
+test_expect_success 'info --url added-directory' '
+ test $(cd gitwc; git-svn info --url added-directory) \
+ = "$svnrepo/added-directory"
+ '
+
test_expect_success 'info added-symlink-file' "
cd gitwc &&
ln -s added-file added-symlink-file &&
@@ -126,6 +162,11 @@ test_expect_success 'info added-symlink-file' "
actual.info-added-symlink-file
"
+test_expect_success 'info --url added-symlink-file' '
+ test $(cd gitwc; git-svn info --url added-symlink-file) \
+ = "$svnrepo/added-symlink-file"
+ '
+
test_expect_success 'info added-symlink-directory' "
cd gitwc &&
ln -s added-directory added-symlink-directory &&
@@ -144,6 +185,11 @@ test_expect_success 'info added-symlink-directory' "
actual.info-added-symlink-directory
"
+test_expect_success 'info --url added-symlink-directory' '
+ test $(cd gitwc; git-svn info --url added-symlink-directory) \
+ = "$svnrepo/added-symlink-directory"
+ '
+
# The next few tests replace the "Text Last Updated" value with a
# placeholder since git doesn't have a way to know the date that a
# now-deleted file was last checked out locally. Internally it
@@ -165,6 +211,11 @@ test_expect_success 'info deleted-file' "
git-diff expected.info-deleted-file actual.info-deleted-file
"
+test_expect_success 'info --url file (deleted)' '
+ test $(cd gitwc; git-svn info --url file) \
+ = "$svnrepo/file"
+ '
+
test_expect_success 'info deleted-directory' "
cd gitwc &&
git rm -r -f directory > /dev/null &&
@@ -181,6 +232,11 @@ test_expect_success 'info deleted-directory' "
git-diff expected.info-deleted-directory actual.info-deleted-directory
"
+test_expect_success 'info --url directory (deleted)' '
+ test $(cd gitwc; git-svn info --url directory) \
+ = "$svnrepo/directory"
+ '
+
test_expect_success 'info deleted-symlink-file' "
cd gitwc &&
git rm -f symlink-file > /dev/null &&
@@ -198,6 +254,11 @@ test_expect_success 'info deleted-symlink-file' "
actual.info-deleted-symlink-file
"
+test_expect_success 'info --url symlink-file (deleted)' '
+ test $(cd gitwc; git-svn info --url symlink-file) \
+ = "$svnrepo/symlink-file"
+ '
+
test_expect_success 'info deleted-symlink-directory' "
cd gitwc &&
git rm -f symlink-directory > /dev/null &&
@@ -215,6 +276,11 @@ test_expect_success 'info deleted-symlink-directory' "
actual.info-deleted-symlink-directory
"
+test_expect_success 'info --url symlink-directory (deleted)' '
+ test $(cd gitwc; git-svn info --url symlink-directory) \
+ = "$svnrepo/symlink-directory"
+ '
+
# NOTE: git does not have the concept of replaced objects,
# so we can't test for files in that state.
@@ -227,6 +293,12 @@ test_expect_success 'info unknown-file' "
git-diff expected.info-unknown-file actual.info-unknown-file
"
+test_expect_success 'info --url unknown-file' '
+ test -z $(cd gitwc; git-svn info --url unknown-file \
+ 2> ../actual.info--url-unknown-file) &&
+ git-diff expected.info-unknown-file actual.info--url-unknown-file
+ '
+
test_expect_success 'info unknown-directory' "
mkdir gitwc/unknown-directory svnwc/unknown-directory &&
ptouch gitwc/unknown-directory svnwc/unknown-directory &&
@@ -238,6 +310,13 @@ test_expect_success 'info unknown-directory' "
git-diff expected.info-unknown-directory actual.info-unknown-directory
"
+test_expect_success 'info --url unknown-directory' '
+ test -z $(cd gitwc; git-svn info --url unknown-directory \
+ 2> ../actual.info--url-unknown-directory) &&
+ git-diff expected.info-unknown-directory \
+ actual.info--url-unknown-directory
+ '
+
test_expect_success 'info unknown-symlink-file' "
cd gitwc &&
ln -s unknown-file unknown-symlink-file &&
@@ -254,6 +333,13 @@ test_expect_success 'info unknown-symlink-file' "
actual.info-unknown-symlink-file
"
+test_expect_success 'info --url unknown-symlink-file' '
+ test -z $(cd gitwc; git-svn info --url unknown-symlink-file \
+ 2> ../actual.info--url-unknown-symlink-file) &&
+ git-diff expected.info-unknown-symlink-file \
+ actual.info--url-unknown-symlink-file
+ '
+
test_expect_success 'info unknown-symlink-directory' "
cd gitwc &&
ln -s unknown-directory unknown-symlink-directory &&
@@ -271,4 +357,11 @@ test_expect_success 'info unknown-symlink-directory' "
actual.info-unknown-symlink-directory
"
+test_expect_success 'info --url unknown-symlink-directory' '
+ test -z $(cd gitwc; git-svn info --url unknown-symlink-directory \
+ 2> ../actual.info--url-unknown-symlink-directory) &&
+ git-diff expected.info-unknown-symlink-directory \
+ actual.info--url-unknown-symlink-directory
+ '
+
test_done
--
1.5.3.4
^ permalink raw reply related
* [PATCH 1/3 v3] git-svn: extract reusable code into utility functions
From: David D. Kilzer @ 2007-11-21 19:57 UTC (permalink / raw)
To: Eric Wong; +Cc: git, David D. Kilzer
In-Reply-To: <1195675039-26746-1-git-send-email-ddkilzer@kilzer.net>
Extacted canonicalize_path() in the main package.
Created new Git::SVN::Util package with an md5sum() function. A
new package was created so that Digest::MD5 did not have to be
loaded in the main package. Replaced code in the SVN::Git::Editor
and SVN::Git::Fetcher packages with calls to md5sum().
Extracted the format_svn_date(), parse_git_date() and
set_local_timezone() functions within the Git::SVN::Log package.
Signed-off-by: David D. Kilzer <ddkilzer@kilzer.net>
---
git-svn.perl | 96 ++++++++++++++++++++++++++++++++++++++-------------------
1 files changed, 64 insertions(+), 32 deletions(-)
diff --git a/git-svn.perl b/git-svn.perl
index 5b1deea..98c980f 100755
--- a/git-svn.perl
+++ b/git-svn.perl
@@ -48,7 +48,8 @@ BEGIN {
foreach (qw/command command_oneline command_noisy command_output_pipe
command_input_pipe command_close_pipe/) {
for my $package ( qw(SVN::Git::Editor SVN::Git::Fetcher
- Git::SVN::Migration Git::SVN::Log Git::SVN),
+ Git::SVN::Migration Git::SVN::Log Git::SVN
+ Git::SVN::Util),
__PACKAGE__) {
*{"${package}::$_"} = \&{"Git::$_"};
}
@@ -583,6 +584,17 @@ sub cmd_create_ignore {
});
}
+sub canonicalize_path {
+ my ($path) = @_;
+ # File::Spec->canonpath doesn't collapse x/../y into y (for a
+ # good reason), so let's do this manually.
+ $path =~ s#/+#/#g;
+ $path =~ s#/\.(?:/|$)#/#g;
+ $path =~ s#/[^/]+/\.\.##g;
+ $path =~ s#/$##g;
+ return $path;
+}
+
# get_svnprops(PATH)
# ------------------
# Helper for cmd_propget and cmd_proplist below.
@@ -600,12 +612,7 @@ sub get_svnprops {
# canonicalize the path (otherwise libsvn will abort or fail to
# find the file)
- # File::Spec->canonpath doesn't collapse x/../y into y (for a
- # good reason), so let's do this manually.
- $path =~ s#/+#/#g;
- $path =~ s#/\.(?:/|$)#/#g;
- $path =~ s#/[^/]+/\.\.##g;
- $path =~ s#/$##g;
+ $path = canonicalize_path($path);
my $r = (defined $_revision ? $_revision : $gs->ra->get_latest_revnum);
my $props;
@@ -1043,6 +1050,27 @@ sub linearize_history {
(\@linear_refs, \%parents);
}
+package Git::SVN::Util;
+use strict;
+use warnings;
+use Digest::MD5;
+
+sub md5sum {
+ my $arg = shift;
+ my $ref = ref $arg;
+ my $md5 = Digest::MD5->new();
+ if ($ref eq 'GLOB' || $ref eq 'IO::File') {
+ $md5->addfile($arg) or croak $!;
+ } elsif ($ref eq 'SCALAR') {
+ $md5->add($$arg) or croak $!;
+ } elsif (!$ref) {
+ $md5->add($arg) or croak $!;
+ } else {
+ ::fatal "Can't provide MD5 hash for unknown ref type: '", $ref, "'";
+ }
+ return $md5->hexdigest();
+}
+
package Git::SVN;
use strict;
use warnings;
@@ -2610,7 +2638,6 @@ use strict;
use warnings;
use Carp qw/croak/;
use IO::File qw//;
-use Digest::MD5;
# file baton members: path, mode_a, mode_b, pool, fh, blob, base
sub new {
@@ -2762,9 +2789,7 @@ sub apply_textdelta {
if (defined $exp) {
seek $base, 0, 0 or croak $!;
- my $md5 = Digest::MD5->new;
- $md5->addfile($base);
- my $got = $md5->hexdigest;
+ my $got = Git::SVN::Util::md5sum($base);
die "Checksum mismatch: $fb->{path} $fb->{blob}\n",
"expected: $exp\n",
" got: $got\n" if ($got ne $exp);
@@ -2783,9 +2808,7 @@ sub close_file {
if (my $fh = $fb->{fh}) {
if (defined $exp) {
seek($fh, 0, 0) or croak $!;
- my $md5 = Digest::MD5->new;
- $md5->addfile($fh);
- my $got = $md5->hexdigest;
+ my $got = Git::SVN::Util::md5sum($fh);
if ($got ne $exp) {
die "Checksum mismatch: $path\n",
"expected: $exp\n got: $got\n";
@@ -2837,7 +2860,6 @@ use strict;
use warnings;
use Carp qw/croak/;
use IO::File;
-use Digest::MD5;
sub new {
my ($class, $opts) = @_;
@@ -3141,11 +3163,9 @@ sub chg_file {
$fh->flush == 0 or croak $!;
seek $fh, 0, 0 or croak $!;
- my $md5 = Digest::MD5->new;
- $md5->addfile($fh) or croak $!;
+ my $exp = Git::SVN::Util::md5sum($fh);
seek $fh, 0, 0 or croak $!;
- my $exp = $md5->hexdigest;
my $pool = SVN::Pool->new;
my $atd = $self->apply_textdelta($fbat, undef, $pool);
my $got = SVN::TxDelta::send_stream($fh, @$atd, $pool);
@@ -3859,6 +3879,29 @@ sub run_pager {
exec $pager or ::fatal "Can't run pager: $! ($pager)";
}
+sub format_svn_date {
+ return strftime("%Y-%m-%d %H:%M:%S %z (%a, %d %b %Y)", localtime(shift));
+}
+
+sub parse_git_date {
+ my ($t, $tz) = @_;
+ # Date::Parse isn't in the standard Perl distro :(
+ if ($tz =~ s/^\+//) {
+ $t += tz_to_s_offset($tz);
+ } elsif ($tz =~ s/^\-//) {
+ $t -= tz_to_s_offset($tz);
+ }
+ return $t;
+}
+
+sub set_local_timezone {
+ if (defined $TZ) {
+ $ENV{TZ} = $TZ;
+ } else {
+ delete $ENV{TZ};
+ }
+}
+
sub tz_to_s_offset {
my ($tz) = @_;
$tz =~ s/(\d\d)$//;
@@ -3879,13 +3922,7 @@ sub get_author_info {
$dest->{t} = $t;
$dest->{tz} = $tz;
$dest->{a} = $au;
- # Date::Parse isn't in the standard Perl distro :(
- if ($tz =~ s/^\+//) {
- $t += tz_to_s_offset($tz);
- } elsif ($tz =~ s/^\-//) {
- $t -= tz_to_s_offset($tz);
- }
- $dest->{t_utc} = $t;
+ $dest->{t_utc} = parse_git_date($t, $tz);
}
sub process_commit {
@@ -3939,8 +3976,7 @@ sub show_commit_normal {
my ($c) = @_;
print commit_log_separator, "r$c->{r} | ";
print "$c->{c} | " if $show_commit;
- print "$c->{a} | ", strftime("%Y-%m-%d %H:%M:%S %z (%a, %d %b %Y)",
- localtime($c->{t_utc})), ' | ';
+ print "$c->{a} | ", format_svn_date($c->{t_utc}), ' | ';
my $nr_line = 0;
if (my $l = $c->{l}) {
@@ -3980,11 +4016,7 @@ sub cmd_show_log {
my (@args) = @_;
my ($r_min, $r_max);
my $r_last = -1; # prevent dupes
- if (defined $TZ) {
- $ENV{TZ} = $TZ;
- } else {
- delete $ENV{TZ};
- }
+ set_local_timezone();
if (defined $::_revision) {
if ($::_revision =~ /^(\d+):(\d+)$/) {
($r_min, $r_max) = ($1, $2);
--
1.5.3.4
^ permalink raw reply related
* [PATCH 0/3 v3] Implement git-svn info
From: David D. Kilzer @ 2007-11-21 19:57 UTC (permalink / raw)
To: Eric Wong; +Cc: git, David D. Kilzer
Changes since the last patch series I posted (last night):
- Patch 1/3: No changes.
- Patch 2/3: Only changes to test code.
- Renamed t/t9117-git-svn-info.sh to t/t9119-git-svn-info.sh.
- Removed static expected.* files and reinstated dynamic generation.
- Replaced "touch -c -r" with ptouch (portable/perl touch) function.
(Should this go in t/lib-git-svn.sh?)
- Use sed(1) inline to work around minor "svn info" vs. "git svn info"
difference.
- Minor test name and expected.*/actual.* file name changes.
- Updated comments.
- Patch 3/3: Added 17 more tests (mirroring the existing 18 tests from
Patch 2/3).
"David D. Kilzer" <ddkilzer@kilzer.net> wrote:
> "David D. Kilzer" <ddkilzer@kilzer.net> wrote:
> > Eric Wong <normalperson@yhbt.net> wrote:
> > > Can we expect the output of "svn info" to not change between
> > > versions? I know "svn status" has changed between versions of
> > > svn. I'd prefer if we keep the expected.* files hard-coded
> > > in a test directory and compare those instead. Maybe use sed
> > > to substitute placeholders for timestamps..
> > Done.
> Grrr. I remember the reason I didn't do this in the first place.
> In Patch 2/3, there are now hard-coded directory paths and my
> username in the static expected-* files.
Actually, using "svn info" to dynamically generate the results means
that the tests will break when "svn info" does change, which is a good
thing. In other words, I think we want to know when that happens so
that we can make a decision about whether to support the change or not.
Dave
^ permalink raw reply
* Re: Git in a Nutshell guide
From: Jan Hudec @ 2007-11-21 19:45 UTC (permalink / raw)
To: Jakub Narebski; +Cc: git
In-Reply-To: <fhvs95$5qk$1@ger.gmane.org>
[-- Attachment #1: Type: text/plain, Size: 1800 bytes --]
On Wed, Nov 21, 2007 at 00:57:28 +0100, Jakub Narebski wrote:
> I think that writing proper "Git Guide" aka "The Git Book" is hard because
> of some things:
>
> 1. Git has many useful advanced features. Describing those advanced
> features is not easy. For example git uses multiple branches in single
> repository paradigm freely, which makes learning curve a bit steeper;
> IIRC hgbook describes one branch per repos situation (at least at
> beginning), which is easier.
I think I saw the "sharp curve" and "double sharp curve" paragraphs in other
places besides the the TeXbook. I even have an impression (without actually
looking) that it was documentation of some version control system.
That deals with difficult to read, but it does make it more difficult to
write.
> 2. Git has some historical cruft, including the fact that it began as
> series of low level tools (plumbing) and became proper SCM (acquired
> proper porcelain) later, what can be even now seen in documentation...
Most plumbing can be safely ignored through most of the book or covered by
those "double sharp curve" paragraphs. It unfortunately does make it harder
to write, because the author has to consider what to cover and what to hide.
> 3. Explanation of some features (like object model) would be much easier
> with some graphics (diagrams etc.), but chosen documentation format,
> AsciiDoc, doesn't make it easy...
I dare to disagree here. Asciidoc supports generating image tags for
respective output formats and it really does not look hard. We could have
PNGs and if we wanted higher press quality even SVG or EPS and convert them
to PNGs for the HTML version (and use EPS for latex output).
--
Jan 'Bulb' Hudec <bulb@ucw.cz>
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 189 bytes --]
^ permalink raw reply
* Git Screencast ?
From: Michael Donaghy @ 2007-11-21 13:02 UTC (permalink / raw)
To: git
I am a new user of git and SCMs in general , I have learned a lot from
the docs , irc and just using it , but there are just some concepts that
hare hard to grasp , I am a very visual persion (probably like a lot of
you :) ) , is there a screencast of git somewhere (for free) that can
demonstrate some of the advanced features of git...
(Also...I have seen both Randal (Schwartz) and Linus' (you better know
his last name) presentations at google on git , in which they explain
the ideas behind git more than the actual usage,
Thanks
---Mike Donaghy-----------
---Mike@mikedonaghy.org---
---http://mikedonaghy.org-
^ permalink raw reply
* Re: gitweb: kernel versions in the history (feature request, probably)
From: Jarek Poplawski @ 2007-11-21 19:29 UTC (permalink / raw)
To: Kay Sievers; +Cc: J. Bruce Fields, Petr Baudis, linux-kernel, git
In-Reply-To: <3ae72650711210806v1e7daa2fq729a7593def99ef7@mail.gmail.com>
Kay Sievers wrote, On 11/21/2007 05:06 PM:
> On Nov 21, 2007 8:52 AM, Jarek Poplawski <jarkao2@o2.pl> wrote:
>> On Tue, Nov 20, 2007 at 10:20:09PM -0500, J. Bruce Fields wrote:
>>> On Wed, Nov 21, 2007 at 12:30:23AM +0100, Jarek Poplawski wrote:
>>>> I don't know git, but it seems, at least if done for web only, this
>>>> shouldn't be so 'heavy'. It could be a 'simple' translation of commit
>>>> date by querying a small database with kernel versions & dates.
>>> If I create a commit in my linux working repo today, but Linus doesn't
>>> merge it into his repository until after he releases 2.6.24, then my
>>> commit will be created with an earlier date than 2.6.24, even though it
>>> isn't included until 2.6.25.
>>>
>>> So you have to actually examine the history graph to figure this out
>>> this sort of thing.
>> Of course, you are right, and I probably miss something, but to be
>> sure we think about the same thing let's look at some example: so, I
>> open a page with current Linus' tree, go to something titled:
>> /pub/scm / linux/kernel/git/torvalds/linux-2.6.git / history
>>
>> and see:
>> 2007-10-10 Stephen Hemminger [NET]: Make NAPI polling independent ...
>> and just below something with 2007-08-14 date.
>>
>> Accidentally, I can remember this patch introduced many changes, and
>> this big interval in dates suggests some waiting. Then I look at the
>> commit, and there are 2 dates visible, so the patch really was created
>> earlier. Then I go back to:
>> /pub/scm / linux/kernel/git/torvalds/linux-2.6.git / summary
>>
>> and at the bottom I can see this:
>>
>> ...
>> tags
>> 4 days ago v2.6.24-rc3 Linux 2.6.24-rc3
>> 2 weeks ago v2.6.24-rc2 Linux 2.6.24-rc2
>> 4 weeks ago v2.6.24-rc1 Linux 2.6.24-rc1
>> 6 weeks ago v2.6.23 Linux 2.6.23
>>
>> which drives me crazy, because, without looking at the calendar, and
>> calculator, I don't really know which month was 6 weeks ago, and 4
>> days ago, either!
>>
>> So, I go to the: http://www.eu.kernel.org/pub/linux/kernel/v2.6/,
>> do some scrolling, look at this:
>> ChangeLog-2.6.23 09-Oct-2007 20:38 3.8M
>>
>> and only now I can guess, this napi patch didn't manage to 2.6.23.
>> Of course, usually I've to do a few more clicks and reading to make
>> sure where it really started.
>>
>> So, this could suggest this 2007-10-10 (probably stored with time
>> too), could be useful here... but it seems, I'm wrong.
>>
>> Of course, this problem doesn't look so hard if we forget about
>> git internals: I can imagine keeping a simple database, which
>> could simply retrieve commit numbers from these ChangeLogs, and
>> connecting this with gitweb's commit page as well... For
>> performance reasons, doing it only for stable and testing, so with
>> -rc 'precision' would be very helpful too.
>
> The "plain" view of the patch has the "version" included:
> http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commitdiff_plain;h=bea3348eef27e6044b6161fd04c3152215f96411
>
> From: Stephen Hemminger <shemminger@linux-foundation.org>
> Date: Wed, 3 Oct 2007 23:41:36 +0000 (-0700)
> Subject: [NET]: Make NAPI polling independent of struct net_device objects.
> X-Git-Tag: v2.6.24-rc1~1454^2~841
>
> Is that what you are looking for?
>
YeeeS!!! You are a genius with eagle's eyes!
I've suspected from the beginning something like this has to be
there... And I really tried to find this before sending this. But,
as a matter of fact I didn't even try this "plain" or rather "raw",
because I've somehow thought "raw" is just plain text, so the same
only without html tags!? So, now I know, and it's enough to me. But,
... maybe it should be on this "complex" page as well?
Thanks very much,
Jarek P.
PS: I hope eagles can see in English at least the same as in Polish,
and more than I can see in my dictionary now!
^ permalink raw reply
* [PATCH] builtin-commit: Include the diff in the commit message when verbose.
From: Kristian Høgsberg @ 2007-11-21 19:10 UTC (permalink / raw)
To: gitster; +Cc: git, Kristian Høgsberg
run_diff_index() and the entire diff machinery is hard coded to output
to stdout, so just redirect that and restore it when done.
Signed-off-by: Kristian Høgsberg <krh@redhat.com>
---
builtin-commit.c | 24 +++++++++++++++++++++++-
1 files changed, 23 insertions(+), 1 deletions(-)
diff --git a/builtin-commit.c b/builtin-commit.c
index 446a252..d5b8479 100644
--- a/builtin-commit.c
+++ b/builtin-commit.c
@@ -277,6 +277,7 @@ static char *prepare_index(const char **files, const char *prefix)
static int run_status(FILE *fp, const char *index_file, const char *prefix)
{
struct wt_status s;
+ int saved_stdout;
wt_status_prepare(&s);
s.prefix = prefix;
@@ -290,8 +291,23 @@ static int run_status(FILE *fp, const char *index_file, const char *prefix)
s.index_file = index_file;
s.fp = fp;
+ fflush(fp);
+
+ /* Sigh, the entire diff machinery is hardcoded to output to
+ * stdout. Do the dup-dance...*/
+ saved_stdout = dup(STDOUT_FILENO);
+ if (saved_stdout < 0 || dup2(fileno(fp), STDOUT_FILENO) < 0)
+ die("couldn't redirect stdout\n");
+
wt_status_print(&s);
+ fflush(fp);
+ fflush(stdout);
+
+ if (dup2(saved_stdout, STDOUT_FILENO) < 0)
+ die("couldn't restore stdout\n");
+ close(saved_stdout);
+
return s.commitable;
}
@@ -661,7 +677,7 @@ int cmd_commit(int argc, const char **argv, const char *prefix)
int header_len;
struct strbuf sb;
const char *index_file, *reflog_msg;
- char *nl;
+ char *nl, *p;
unsigned char commit_sha1[20];
struct ref_lock *ref_lock;
@@ -757,6 +773,12 @@ int cmd_commit(int argc, const char **argv, const char *prefix)
rollback_index_files();
exit(1);
}
+
+ /* Truncate the message just before the diff, if any. */
+ p = strstr(sb.buf, "\ndiff --git a/");
+ if (p != NULL)
+ strbuf_setlen(&sb, p - sb.buf);
+
stripspace(&sb, 1);
if (sb.len < header_len || message_is_empty(&sb, header_len)) {
rollback_index_files();
--
1.5.3.4.206.g58ba4
^ permalink raw reply related
* Re: [PATCH] autoconf: Add tests for memmem, strtoumax and mkdtemp functions
From: Jakub Narebski @ 2007-11-21 18:47 UTC (permalink / raw)
To: Shawn O. Pearce; +Cc: git
In-Reply-To: <20071121065858.GU14735@spearce.org>
Shawn O. Pearce wrote:
> Jakub Narebski <jnareb@gmail.com> wrote:
>> By the way, do you have idea how to test for the following
>> in configure.ac:
>>
>> * Define NO_PREAD if you have a problem with pread() system call (e.g.
>> cygwin.dll before v1.5.22).
>>
>> - what is the problem? how to detect it?
>
> This also appears to be broken on HP-UX (e.g. we need to set
> NO_PREAD there). Thiago on IRC talked about this the other day
> when he was trying to build git on a bunch of different systems.
>
> Unfortunately this may just need to be an OS based test. The code
> compiles just fine but when index-pack tries to use pread to walk
> back through the deltas and generate their SHA-1s it barfs without
> an error code. I suspect the failure is pread claiming it put the
> data into the user buffer but not actually doing so, which causes
> zlib's inflate() to then see data corruption.
Can you write a short program which demonstrates this error (either
fails with some error code, or produces wrong output)? That would be
enough for configure.ac (see for example NO_C99_FORMAT in configure.ac)
Unless this is Schroedinger bug...
--
Jakub Narebski
Poland
^ permalink raw reply
* Re: [PATCH] avoid "defined but not used" warning for fetch_objs_via_walker
From: Daniel Barkalow @ 2007-11-21 18:05 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Jeff King, git
In-Reply-To: <7v63zwhy4i.fsf@gitster.siamese.dyndns.org>
On Tue, 20 Nov 2007, Junio C Hamano wrote:
> Jeff King <peff@peff.net> writes:
>
> > Because this function is static and used only by the
> > http-walker, when NO_CURL is defined, gcc emits a "defined
> > but not used" warning.
> >
> > Signed-off-by: Jeff King <peff@peff.net>
> > ---
> > On master. I like to compile with -Werror to make sure I don't miss
> > warnings as the compile scrolls by.
> >
> > This fix feels a little wrong, since the function isn't specific to http
> > support, but hopefully the comment should be obvious if we ever add
> > another similar commit walker that needs it.
>
> Yeah, while I share your -Werror desire it sure feels a bit
> dirty. As it does not look like we will be taking any new
> walkers, I think your patch is reasonable, though.
I think we're likely to do sftp someday, but everything is likely to get
reorganized before that anyway.
-Daniel
*This .sig left intentionally blank*
^ permalink raw reply
* Re: Wishlist for a bundle-only transport mode
From: Jakub Narebski @ 2007-11-21 17:52 UTC (permalink / raw)
To: Johannes Schindelin; +Cc: Santi Béjar, git
In-Reply-To: <Pine.LNX.4.64.0711211719330.27959@racer.site>
On Wed, 21 Nov 2007, Johannes Schindelin wrote:
> On Wed, 21 Nov 2007, Jakub Narebski wrote:
>> Johannes Schindelin wrote:
>>> On Wed, 21 Nov 2007, Jakub Narebski wrote:
>>>
>>>> That has the disadvantage of pushing to bundle when you make an error
>>>> in the lastpart of path to existing repository.
>>>
>>> As I wrote in another reply, I would not allow overwriting an existing
>>> file.
>>
>>> Specifying a non-existing file should be good enough.
>>
>> What I meant here that if you do "git push /some/path/to/rpeo.git", with
>> mistake in the last part of path to repository, you would end up with a
>> bundle, and you would have to really watch what happened to catch the
>> error.
>
> I use tab completion all the time, so this would not happen to me. IMHO
> that is a lesser issue than to introduce a "protocol".
When I copy'n'paste pathname I sometimes catch return / linefeed in
the middle, ending with incorect pathname (which would create bundle).
Tab completon is not always solution (tab completion can be slow,
or nonexistent).
[cut]
But I agree that because "git create bundle" needs refspecs _and revlist_,
while "git push" gets only refspecs because it calculates revlist it would
be better to have to use "git bundle create" to create bundle.
Contrary to "git clone <bundle>" which should just work IMHO.
--
Jakub Narebski
Poland
^ permalink raw reply
* Re: Wishlist for a bundle-only transport mode
From: Johannes Schindelin @ 2007-11-21 17:29 UTC (permalink / raw)
To: Jakub Narebski; +Cc: git
In-Reply-To: <fi1ojd$pva$1@ger.gmane.org>
Hi,
On Wed, 21 Nov 2007, Jakub Narebski wrote:
> We would also need "git ls-remote <bundle>" and "git fsck <bundle>" to
> demote git-bundle to porcelain status :-)
git ls-remote <bundle> worked, last time I checked (15 seconds ago). But
git fsck? Since when does something like "git fsck
git://repo.or.cz/git.git" work?
Besides, "git bundle verify <bundle>" works quite well.
Ciao,
Dscho
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox