Git development
 help / color / mirror / Atom feed
* [PATCH v4 3/4] gitk: add "--no-replace-objects" option
From: Christian Couder @ 2009-11-22  6:56 UTC (permalink / raw)
  To: Junio C Hamano
  Cc: git, Michael J Gruber, Jakub Narebski, Johannes Sixt, bill lam,
	Andreas Schwab, Paul Mackerras
In-Reply-To: <20091122064652.4811.38993.chriscool@tuxfamily.org>

Replace refs are useful to change some git objects after they
have started to be shared between different repositories. One
might want to ignore them to see the original state, and
"--no-replace-objects" option can be used from the command
line to do so.

This option simply sets the GIT_NO_REPLACE_OBJECTS environment
variable, and that is enough to make gitk ignore replace refs.

The GIT_NO_REPLACE_OBJECTS is set to "1" instead of "" as it is
safer on some platforms, thanks to Johannes Sixt and Michael J
Gruber.

Tested-by: Michael J Gruber <git@drmicha.warpmail.net>
Signed-off-by: Christian Couder <chriscool@tuxfamily.org>
---
 gitk-git/gitk |    5 ++++-
 1 files changed, 4 insertions(+), 1 deletions(-)

diff --git a/gitk-git/gitk b/gitk-git/gitk
index a0214b7..c586b93 100644
--- a/gitk-git/gitk
+++ b/gitk-git/gitk
@@ -128,7 +128,7 @@ proc unmerged_files {files} {
 }
 
 proc parseviewargs {n arglist} {
-    global vdatemode vmergeonly vflags vdflags vrevs vfiltered vorigargs
+    global vdatemode vmergeonly vflags vdflags vrevs vfiltered vorigargs env
 
     set vdatemode($n) 0
     set vmergeonly($n) 0
@@ -208,6 +208,9 @@ proc parseviewargs {n arglist} {
 		# git rev-parse doesn't understand --merge
 		lappend revargs --gitk-symmetric-diff-marker MERGE_HEAD...HEAD
 	    }
+	    "--no-replace-objects" {
+		set env(GIT_NO_REPLACE_OBJECTS) "1"
+	    }
 	    "-*" {
 		# Other flag arguments including -<n>
 		if {[string is digit -strict [string range $arg 1 end]]} {
-- 
1.6.5.1.gaf97d

^ permalink raw reply related

* [PATCH v4 1/4] Documentation: fix typos and spelling in git-replace documentation
From: Christian Couder @ 2009-11-22  6:56 UTC (permalink / raw)
  To: Junio C Hamano
  Cc: git, Michael J Gruber, Jakub Narebski, Johannes Sixt, bill lam,
	Andreas Schwab, Paul Mackerras
In-Reply-To: <20091122064652.4811.38993.chriscool@tuxfamily.org>

This patch fix a missing "s" at the end of an occurence of
"--no-replace-objects" and, while at it, it also improves spelling
and rendering of the git-replace man page.

Signed-off-by: Christian Couder <chriscool@tuxfamily.org>
---
 Documentation/git-replace.txt |   21 +++++++++++----------
 1 files changed, 11 insertions(+), 10 deletions(-)

diff --git a/Documentation/git-replace.txt b/Documentation/git-replace.txt
index 8adc1ef..69f704f 100644
--- a/Documentation/git-replace.txt
+++ b/Documentation/git-replace.txt
@@ -17,31 +17,32 @@ DESCRIPTION
 Adds a 'replace' reference in `.git/refs/replace/`
 
 The name of the 'replace' reference is the SHA1 of the object that is
-replaced. The content of the replace reference is the SHA1 of the
+replaced. The content of the 'replace' reference is the SHA1 of the
 replacement object.
 
-Unless `-f` is given, the replace reference must not yet exist in
+Unless `-f` is given, the 'replace' reference must not yet exist in
 `.git/refs/replace/` directory.
 
-Replace references will be used by default by all git commands except
-those doing reachability traversal (prune, pack transfer and fsck).
+Replacement references will be used by default by all git commands
+except those doing reachability traversal (prune, pack transfer and
+fsck).
 
-It is possible to disable use of replacement refs for any command
-using the --no-replace-objects option just after "git".
+It is possible to disable use of replacement references for any
+command using the `--no-replace-objects` option just after 'git'.
 
-For example if commit "foo" has been replaced by commit "bar":
+For example if commit 'foo' has been replaced by commit 'bar':
 
 ------------------------------------------------
-$ git --no-replace-object cat-file commit foo
+$ git --no-replace-objects cat-file commit foo
 ------------------------------------------------
 
-show information about commit "foo", while:
+shows information about commit 'foo', while:
 
 ------------------------------------------------
 $ git cat-file commit foo
 ------------------------------------------------
 
-show information about commit "bar".
+shows information about commit 'bar'.
 
 OPTIONS
 -------
-- 
1.6.5.1.gaf97d

^ permalink raw reply related

* [PATCH v4 0/4] add new GIT_NO_REPLACE_OBJECTS env variable
From: Christian Couder @ 2009-11-22  6:56 UTC (permalink / raw)
  To: Junio C Hamano
  Cc: git, Michael J Gruber, Jakub Narebski, Johannes Sixt, bill lam,
	Andreas Schwab, Paul Mackerras

Here are all the patches together.

The other change (except putting them together) is that I tried to
improve the commit messages as suggested by Paul and Junio.

The first patch contains documentation fixes and could be applied to
"maint".

Christian Couder (4):
  Documentation: fix typos and spelling in git-replace documentation
  replace: use a GIT_NO_REPLACE_OBJECTS env variable
  gitk: add "--no-replace-objects" option
  Documentation: replace: talk a little bit about
    GIT_NO_REPLACE_OBJECTS

 Documentation/git-replace.txt |   24 ++++++++++++++----------
 cache.h                       |    1 +
 connect.c                     |    1 +
 environment.c                 |    2 ++
 git.c                         |    3 +++
 gitk-git/gitk                 |    5 ++++-
 t/t6050-replace.sh            |   17 +++++++++++++++++
 7 files changed, 42 insertions(+), 11 deletions(-)

^ permalink raw reply

* Re: [PATCH] submodule.c: Squelch a "use before assignment" warning
From: Junio C Hamano @ 2009-11-22  3:32 UTC (permalink / raw)
  To: Christoph Bartoschek; +Cc: git
In-Reply-To: <7vws1jl0xp.fsf@alter.siamese.dyndns.org>

Junio C Hamano <gitster@pobox.com> writes:

> Christoph Bartoschek <bartoschek@gmx.de> writes:
>
>> Why is the compiler not complaining about the fake initalization? For 
>> initialization a value is used that is not initialized.
>
> That is a fairly well established idiom to tell gcc "you may mistakenly
> think it isn't, but this is used".

Sorry, but I was called away from the keyboard in mid sentence.  It should
have read "...this is used after getting assigned, so do not worry".

But I need to clarify a few things about this issue.

As the maintainer, I do not like a fake initialisation myself very much.
It is a declaration that "left" is always assigned before getting used by
the person who wrote _that particular version_, but later updates to the
code might introduce a codepath to incorrectly use "left" before getting
assinged to, and the fake initialisation will prevent the compiler from
catching it.

When the variable in question is a pointer, assigning NULL instead of
"left = left" will at least give us a predictable and more reproducible
breakage when later updates break the code.  I wouldn't have minded if
David's patch were to update both the existing fake initialisation and the
new one to assign NULL.  At least dereferencing such a pointer will give
us a segfault reliably.  But unfortunately there is no such "magic" values
for variables of other types (e.g. int) to help us catch uninitialized use
of variables at runtime.

By the way, if a static analyser is meant to be useful for real-world
programs, as opposed to merely an academic exercise, it should know this
convention; like it or not, it is used fairly widely.  That is, it should
check "left" is assigned before used in the rest of the function without
this "gcc hack" initializer, and if the only questionable use of "left" is
the RHS of this fake initialisation, should refrain from warning.

^ permalink raw reply

* Re: [PATCH] submodule.c: Squelch a "use before assignment" warning
From: Junio C Hamano @ 2009-11-22  2:59 UTC (permalink / raw)
  To: Christoph Bartoschek; +Cc: git
In-Reply-To: <c5plt6-5me.ln1@burns.bruehl.pontohonk.de>

Christoph Bartoschek <bartoschek@gmx.de> writes:

> Why is the compiler not complaining about the fake initalization? For 
> initialization a value is used that is not initialized.

That is a fairly well established idiom to tell gcc "you may mistakenly
think it isn't, but this is used".

^ permalink raw reply

* Re: [PATCH] send-email: new 'add-envelope' option
From: Junio C Hamano @ 2009-11-22  2:58 UTC (permalink / raw)
  To: Felipe Contreras; +Cc: Jeff King, git
In-Reply-To: <94a0d4530911211159l1fadad0ldb0d760439ceb57@mail.gmail.com>

Felipe Contreras <felipe.contreras@gmail.com> writes:

> There are no tests for 'envelope-sender', so I don't think it should
> be a requirement for this patch to do so....

The fact that the lack of test was pointed out as a problem makes it a
requirement.  Others' earlier mistakes are not an excuse for you to do a
poor job.

I do use --envelope-sender when sending patches out via msmtp.  What
wonderful things this patch adds am I missing in my current setup?

^ permalink raw reply

* Re: [PATCH/RFC 0/3] git rerere unresolve file
From: Junio C Hamano @ 2009-11-22  2:53 UTC (permalink / raw)
  To: Johannes Sixt; +Cc: git
In-Reply-To: <200911211958.40872.j6t@kdbg.org>

Johannes Sixt <j6t@kdbg.org> writes:

> ... But 
> there is no other way to remove an incorrect resolution short of purging the 
> whole rr-cache.

No, no no, no.  You do not have to.

As long as you can find out the <preimage,postimage> pair, iow, the
subdirectory used by .git/rr-cache/, you can remove only "postimage" from
there and redo your merge.  "ls -t1 .git/rr-cache/*/thisimage | head"
would be one way to manually find out which one it is.

For example, let's take this merge as an example.

commit 697eb20061dfa00838df32ac24c414dfb4a1f920
Merge: bba637b 46b77a6
Author: Junio C Hamano <gitster@pobox.com>

    Merge branch 'jk/1.7.0-status' into jch

You may not have rerere entries for this, so follow me along for a while.

 $ git checkout bba637b
 $ git merge 46b77a6

This will have a conflict.  We are priming your rerere database, so we
cheat (notice the last dot ".").

 $ git checkout 697eb200 -- .
 $ git rerere

Now reset it away, and redo the merge

 $ git reset --hard
 $ git checkout bba637b
 $ git merge 46b77a6

It will autoresolve the way I resolved in 697eb200

Suppose you do not like the resolution; you can do:

    $ git checkout --conflict=merge Documentation/git-commit.txt
    $ git rerere

to force updating "thisimage".  The newest one is the entry you are
looking for.

    $ ls -1t .git/rr-cache/*/thisimage | head -n 1
    .git/rr-cache/02aac459b0c777f92a8ca6f1e449e6760d366c20/thisimage

I can remove "postimage" from the directory, recreate conflict again,
run rerere to remember it anew, resolve and have rerere remember the new
resolution.

A tool support to compute the conflict hash would be part of a nice
solution.

    $ git checkout --conflict=merge Documentation/git-commit.txt
    $ git rerere hash
    02aac459b0c777f92a8ca6f1e449e6760d366c20 Documentation/git-commit.txt    

Instead of giving "hash" subcommand and having the user to remove
postimage from the directory, the tool can remove it, of course.

    $ git checkout --conflict=merge Documentation/git-commit.txt
    $ git rerere forget Documentation/git-commit.txt
    02aac459b0c777f92a8ca6f1e449e6760d366c20 Documentation/git-commit.txt    
    $ edit Documentation/git-commit.txt ;# come up with a better resolution 
    $ git rerere ;# record it

The attached are rough sketch of such "hash/forget" subcommands.

I however think the best user experience would go like this:

 * Run "git merge"; rerere replays an earlier resolution.

   $ git merge ...

   User decides that it is not a desirable one.

 * User fixes it and creates a better resolution in the work tree.  The
   user may fix-up the autoresolution or the user may first do "checkout
   --conflict=merge" and resolves the conflict from scratch.

   It does not matter how the updated resolution is prepared in the work
   tree.

 * Then the user tells rerere that "this is the corrected resolution",
   perhaps

   $ git rerere update Documentation/git-commit.txt

   This will

   - Internally recompute the original conflicted state, i.e. run
     "checkout --conflict=merge Documentation/git-commit.txt" in-core;

   - feed it to rerere.c::handle_file() to learn the conflict hash;

   - read the user's updated resolution from the work tree, and update
     "postimage" with it.

There is no need to change MERGE_RR at all if you did it the way outlined
in the above.

My "hash" would be more-or-less a useless command.  It still might be
useful as a plumbing command, but it is mostly for debugging.

The "forget" subcommand may be useful, but the real implementation should
be the first half of the "update", iow, recreate conflict in-core in order
to compute the conflict hash, and drop existing "postimage", without
replacing it from the work tree.  We should leave it up to the user using
"checkout --conflict" to reproduce the conflict in the work tree.

 builtin-rerere.c |    4 +++
 rerere.c         |   58 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 rerere.h         |    2 +
 3 files changed, 64 insertions(+), 0 deletions(-)

diff --git a/builtin-rerere.c b/builtin-rerere.c
index 343d6cd..8865313 100644
--- a/builtin-rerere.c
+++ b/builtin-rerere.c
@@ -108,6 +108,10 @@ int cmd_rerere(int argc, const char **argv, const char *prefix)
 
 	if (!strcmp(argv[1], "-h"))
 		usage(git_rerere_usage);
+	else if (!strcmp(argv[1], "hash"))
+		return rerere_report_hash();
+	else if (!strcmp(argv[1], "forget"))
+		return rerere_forget(argv + 2);
 
 	fd = setup_rerere(&merge_rr);
 	if (fd < 0)
diff --git a/rerere.c b/rerere.c
index 29f95f6..4899219 100644
--- a/rerere.c
+++ b/rerere.c
@@ -392,3 +392,61 @@ int rerere(void)
 		return 0;
 	return do_plain_rerere(&merge_rr, fd);
 }
+
+int rerere_forget(const char **path)
+{
+	struct string_list conflict = { NULL, 0, 0, 1 };
+	int i;
+
+	find_conflict(&conflict);
+
+	/*
+	 * Note note note.  I am being lazy here.  The loop should not
+	 * iterate over "path" like this.
+	 *
+	 * It should instead iterate over conflict entries, using "path"
+	 * as pathspec to filter, so that you can say "I am done with
+	 * all the conflict in Documentation/ area".
+	 */
+	for (i = 0; path[i]; i++) { 
+		unsigned char sha1[20];
+		const char *postimage;
+		int ret;
+
+		if (!string_list_has_string(&conflict, path[i])) {
+			error("No such conflicted path %s\n", path[i]);
+			continue;
+		}
+		ret = handle_file(path[i], sha1, NULL);
+		if (ret < 1) {
+			error("No conflict in work tree %s\n", path[i]);
+			continue;
+		}
+		postimage = rerere_path(sha1_to_hex(sha1), "postimage");
+		if (!unlink(postimage))
+			fprintf(stderr, "forgot resolution for %s\n", path[i]);
+		else if (errno == ENOENT)
+			error("no remembered resolution for %s", path[i]);
+		else
+			error("cannot unlink %s: %s", postimage, strerror(errno));
+	}
+	return 0;
+}
+
+int rerere_report_hash(void)
+{
+	struct string_list conflict = { NULL, 0, 0, 1 };
+	int i;
+
+	find_conflict(&conflict);
+	for (i = 0; i < conflict.nr; i++) {
+		const char *path = conflict.items[i].string;
+		unsigned char sha1[20];
+		int ret;
+		ret = handle_file(path, sha1, NULL);
+		if (ret < 1)
+			continue;
+		printf("%s %s\n", sha1_to_hex(sha1), path);
+	}
+	return 0;
+}
diff --git a/rerere.h b/rerere.h
index 13313f3..a10dea9 100644
--- a/rerere.h
+++ b/rerere.h
@@ -7,5 +7,7 @@ extern int setup_rerere(struct string_list *);
 extern int rerere(void);
 extern const char *rerere_path(const char *hex, const char *file);
 extern int has_rerere_resolution(const char *hex);
+extern int rerere_report_hash(void);
+extern int rerere_forget(const char **path);
 
 #endif

^ permalink raw reply related

* Re: Per file configurable eol-style transformations with Git?
From: Junio C Hamano @ 2009-11-22  1:24 UTC (permalink / raw)
  To: Alexander Veit; +Cc: git
In-Reply-To: <1050CAACABF64864A0CF79C957BF773B@helium>

"Alexander Veit" <alexander.veit@gmx.net> writes:

> Jakub Narebski wrote:
>
>> See `crlf` attribute, which can be set, unset, unspecified, set
>> to "input", and used together with core.autocrlf ("true", "false",
>> "input") and core.safecrlf.  Attributes can be set per path (using
>> globbing patterns) in .gitattributes file in tree, or in
>> .git/info/attributes (per repository).
>
> I've already tried 
>
> [core]
>   autoCRLF = true
>
> in the global gitconfig under Windows.

That would not be per-file anyway.

What Jakub suggested makes sense.  You want to read up on
gitattributes(5).

^ permalink raw reply

* Re: [PATCH] git-count-objects: Fix a disk-space under-estimate on Cygwin
From: Junio C Hamano @ 2009-11-22  1:21 UTC (permalink / raw)
  To: Ramsay Jones; +Cc: GIT Mailing-list
In-Reply-To: <4B072D98.6020101@ramsay1.demon.co.uk>

Ramsay Jones <ramsay@ramsay1.demon.co.uk> writes:

> I haven't tried this patch, but I think you may need to add something like
> the following (*not tested*):
>
> --- >8 ---
> diff --git a/compat/cygwin.c b/compat/cygwin.c
> index b4a51b9..7e9edec 100644
> --- a/compat/cygwin.c
> +++ b/compat/cygwin.c
> @@ -53,6 +53,7 @@ static int do_stat(const char *file_name, struct stat *buf, stat_fn_t cygstat)
>  		buf->st_size = (off_t)fdata.nFileSizeLow;
>  #endif
>  		buf->st_blocks = size_to_blocks(buf->st_size);
> +		buf->st_blksize = 512;
>  		filetime_to_timespec(&fdata.ftLastAccessTime, &buf->st_atim);
>  		filetime_to_timespec(&fdata.ftLastWriteTime, &buf->st_mtim);
>  		filetime_to_timespec(&fdata.ftCreationTime, &buf->st_ctim);
> --- >8 ---

Doesn't this contradict with everything you said?

You are forcing st_blksize to 512 but still return the same old st_blocks;
I do not understand what that would achieve.

In your experiments, st_blocks was reported in 1024-byte blocks and that
size coincided with what was reported in st_blksize, and that was the
whole point of the approach taken by the ST_BLOCKS_COUNTS_IN_BLKSIZE
patch.

^ permalink raw reply

* Re: Per file configurable eol-style transformations with Git?
From: Alexander Veit @ 2009-11-21 23:49 UTC (permalink / raw)
  To: git
In-Reply-To: <m3tywnbmpj.fsf@localhost.localdomain>

Jakub Narebski wrote:

> See `crlf` attribute, which can be set, unset, unspecified, set
> to "input", and used together with core.autocrlf ("true", "false",
> "input") and core.safecrlf.  Attributes can be set per path (using
> globbing patterns) in .gitattributes file in tree, or in
> .git/info/attributes (per repository).

I've already tried 

[core]
  autoCRLF = true

in the global gitconfig under Windows. After git clone an immediate
git diff shows every line changed in certain files:

diff --git a/c_crlf_text.txt b/c_crlf_text.txt
index 3b0a76f..3473745 100644
--- a/c_crlf_text.txt
+++ b/c_crlf_text.txt
@@ -1,5 +1,5 @@
-z1
-z2
-z3
-z4
-
+z1
+z2
+z3
+z4
+

file * on Windows:
c___lf_text.txt;  ASCII text, with CRLF line terminators
c_crlf_text.txt;  ASCII text, with CRLF line terminators


file * on Linux
c_crlf_text.txt:  ASCII text, with CRLF line terminators
c___lf_text.txt:  ASCII text

I don't know if this behaviour is supposed to be correct,
but to me it seems to be wrong.

git version 1.6.5.1.1367.gcd48

-- 
Cheers,
Alex

^ permalink raw reply related

* [PATCH v2] Let core.excludesfile default to ~/.gitexcludes.
From: Matthieu Moy @ 2009-11-21 22:00 UTC (permalink / raw)
  To: git, gitster; +Cc: Matthieu Moy
In-Reply-To: <4B06A7EE.2090801@atlas-elektronik.com>

Most users will set it to ~/.gitsomething. ~/.gitignore would conflict
with per-directory ignore file if ~/ is managed by Git, so ~/.gitexcludes
is a sane default.

Signed-off-by: Matthieu Moy <Matthieu.Moy@imag.fr>
---
Change since v1 : just changed gitignore -> gitexcludes.

 Documentation/config.txt |    1 +
 dir.c                    |    9 ++++++++-
 2 files changed, 9 insertions(+), 1 deletions(-)

diff --git a/Documentation/config.txt b/Documentation/config.txt
index 39d1226..13871a6 100644
--- a/Documentation/config.txt
+++ b/Documentation/config.txt
@@ -384,6 +384,7 @@ core.excludesfile::
 	of files which are not meant to be tracked.  "~/" is expanded
 	to the value of `$HOME` and "~user/" to the specified user's
 	home directory.  See linkgit:gitignore[5].
+	Default: ~/.gitexcludes.
 
 core.editor::
 	Commands such as `commit` and `tag` that lets you edit
diff --git a/dir.c b/dir.c
index d0999ba..cf3d8b4 100644
--- a/dir.c
+++ b/dir.c
@@ -914,9 +914,16 @@ void setup_standard_excludes(struct dir_struct *dir)
 
 	dir->exclude_per_dir = ".gitignore";
 	path = git_path("info/exclude");
+	if (!excludes_file) {
+		const char *home = getenv("HOME");
+		char *user_gitignore = malloc(strlen(home) + strlen("/.gitexcludes") + 1);
+		strcpy(user_gitignore, home);
+		strcat(user_gitignore, "/.gitexcludes");
+		excludes_file = user_gitignore;
+	}
 	if (!access(path, R_OK))
 		add_excludes_from_file(dir, path);
-	if (excludes_file && !access(excludes_file, R_OK))
+	if (!access(excludes_file, R_OK))
 		add_excludes_from_file(dir, excludes_file);
 }
 
-- 
1.6.5.3.435.g5f2e3.dirty

^ permalink raw reply related

* Re: [PATCH] gitk: Use git-difftool for external diffs
From: David Aguilar @ 2009-11-21 21:47 UTC (permalink / raw)
  To: Junio C Hamano
  Cc: Paul Mackerras, peff@peff.net, sam@vilain.net,
	git@vger.kernel.org, markus.heidelberg@web.de
In-Reply-To: <7veinsx6lj.fsf@alter.siamese.dyndns.org>

On Nov 20, 2009, at 12:51 PM, Junio C Hamano <gitster@pobox.com> wrote:

> I do not read Tcl very well but I am guessing that in gitk you specify
>>>
>>
> what tool to run (e.g. "frobanodiff -z"), gitk feeds you two temporary
> files on the filesystem to compare (e.g. "frobanodiff -z $tmp1  
> $tmp2"),
> and your command line is responsible for giving satisfying diff  
> experience
> to the end user.
>
> I see three possible approaches:
>
> * Teach "git-difftool" a mode to compare two arbitrary files on the
>   filesytem, and set that as "External Diff" command that takes the
>   filenames as extra two parameters, just like any other "External  
> Diff"
>   programs given to gitk does.  This is the least palatable, as it  
> won't
>   solve the read-only repository issue at all (it only allows you the
>   logic to choose the configured difftool backend program).
>
> * Instead of disabling the traditional "External Diff" and taking it  
> over
>   like your patch did, add a new codepath for "Difftool" that feeds  
> the
>   commit IDs and paths the way git-difftool expects.  The user can use
>   both, and the issue of read-only repository is solved when  
> "Difftool"
>   is used (but not "External Diff").
>
> * Take over "External Diff" codepath exactly like your patch did, but
>   teach "git-difftool" a new command line option to name an  
> unconfigured
>   external program that takes two filenames.  When "External Diff"
>   program is *not* configured in gitk, the command line to invoke
>   difftool would be exactly as in your patch, i.e. "difftool --no- 
> prompt
>   $from $to -- $path".  Otherwise, when gitk is configured to use an
>   external program, e.g. "frobanodiff -z", for "External Diff", you  
> pass
>   that command line to "git-difftool" via that new option, e.g.
>
>     difftool --no-prompt --extcmd="frobanodiff -z" $from $to -- $path
>
>   Then difftool is responsible for preparing the two necessary  
> temporary
>   files out of the given information ($from/$to/$path) and feeding  
> them
>   to "frobanodiff -z" command line.
>
>   Maybe such --extcmd support already exists in difftool, in which  
> case
>   my earlier suspicion that difftool is not as flexible would be  
> false.

Sounds good.  Adding --extcmd should be nice and straightforward.   
Markus mentioned the need for a diff.guitool variable that would be  
tested for in the gitk case so it sounds like having a --gui option to  
let difftool know to do that should then cover all the bases.

It's looking like we'll have ourselves a small difftool patch series  
soon.  Thanks all,

-- 
         David 
  

^ permalink raw reply

* Re: Per file configurable eol-style transformations with Git?
From: Jakub Narebski @ 2009-11-21 21:18 UTC (permalink / raw)
  To: Alexander Veit; +Cc: git
In-Reply-To: <9ED0EB52C33C41209726C6F4DB7FC194@helium>

"Alexander Veit" <alexander.veit@gmx.net> writes:

> we have projects that contain text files that need to
> have different end-of-line sequences, depending on the
> type of file, and depending on the operating system where
> they are checked out.
> 
> There are files that have
> 
>  - LF line breaks on each platform,
>  - CR LF line breaks on each platform, or
>  - either LF or CR LF line breaks, depending on the
>    platform's native end-of-line style.
> 
> With Subversion, the correct behaviour in checkouts, commits,
> diffs, or merges can easily be achieved by setting the appropriate
> svn:eol-style [*].
> 
> As I understand the Git documentation there's no such concept as a
> repository end-of-line style, or as an end-of-line transformation
> between repository and working copy.
> 
> So I wonder if it is possible to mimic Subversion's end-of-line handling
> with Git, especially for the svn:eol-style=native.

See `crlf` attribute, which can be set, unset, unspecified, set to
"input", and used together with core.autocrlf ("true", "false", "input")
and core.safecrlf.  Attributes can be set per path (using globbing
patterns) in .gitattributes file in tree, or in .git/info/attributes
(per repository).

HTH
-- 
Jakub Narebski
Poland
ShadeHawk on #git

^ permalink raw reply

* Re: [PATCH] submodule.c: Squelch a "use before assignment" warning
From: Christoph Bartoschek @ 2009-11-21 18:46 UTC (permalink / raw)
  To: git
In-Reply-To: <7v8we17ha9.fsf@alter.siamese.dyndns.org>

Junio C Hamano wrote:

> David Aguilar <davvid@gmail.com> writes:
> 
>> i686-apple-darwin9-gcc-4.0.1 (GCC) 4.0.1 (Apple Inc. build 5493) compiler
>> (and probably others) mistakenly thinks variable 'right' is used
>> before assigned.  Work it around by giving it a fake initialization.
> 
> We see the same "fake initialization" of 'left' on the same line.  By
> initializing it to NULL, you are hinting that initializing 'right' to
> NULL actually means something.

Why is the compiler not complaining about the fake initalization? For 
initialization a value is used that is not initialized.

At least a static analyzer complains: 

"submodule.c", line 41: The variable `left' is used before its 
initialization 

Christoph

^ permalink raw reply

* Per file configurable eol-style transformations with Git?
From: Alexander Veit @ 2009-11-21 20:21 UTC (permalink / raw)
  To: git

Hi,

we have projects that contain text files that need to
have different end-of-line sequences, depending on the
type of file, and depending on the operating system where
they are checked out.

There are files that have

 - LF line breaks on each platform,
 - CR LF line breaks on each platform, or
 - either LF or CR LF line breaks, depending on the
   platform's native end-of-line style.

With Subversion, the correct behaviour in checkouts, commits,
diffs, or merges can easily be achieved by setting the appropriate
svn:eol-style [*].

As I understand the Git documentation there's no such concept as a
repository end-of-line style, or as an end-of-line transformation
between repository and working copy.

So I wonder if it is possible to mimic Subversion's end-of-line handling
with Git, especially for the svn:eol-style=native.

-- 
Regards,
Alex


[*]
http://svnbook.red-bean.com/nightly/de/svn-book.html#svn.advanced.props.special.eol-style

^ permalink raw reply

* Re: [PATCH] send-email: new 'add-envelope' option
From: Felipe Contreras @ 2009-11-21 19:59 UTC (permalink / raw)
  To: Jeff King; +Cc: git
In-Reply-To: <20091121193600.GA3296@coredump.intra.peff.net>

On Sat, Nov 21, 2009 at 9:36 PM, Jeff King <peff@peff.net> wrote:
> So my first thought was "how in the world is this different from setting
> the envelope sender?"
>
> Reading the code, it seems:

[...]

> that this is a boolean to mean "use the from address as the envelope
> sender".
>
> It was of course all the more confusing for not being documented at all,
> but even if documented,

Right, I forgot the one-liner for the help.

> --envelope-from is IMHO confusingly similar to
> --envelope-sender. Maybe --use-from-in-envelope would be a better name?

Ok. I don't have any opinion on the name.

> And of course, your patch is missing docs and tests.

There are no tests for 'envelope-sender', so I don't think it should
be a requirement for this patch to do so. I'll add the documentation
though.

Will resend v2.

-- 
Felipe Contreras

^ permalink raw reply

* Re: [PATCH] send-email: new 'add-envelope' option
From: Jeff King @ 2009-11-21 19:36 UTC (permalink / raw)
  To: Felipe Contreras; +Cc: git
In-Reply-To: <1258825410-28592-1-git-send-email-felipe.contreras@gmail.com>

On Sat, Nov 21, 2009 at 07:43:30PM +0200, Felipe Contreras wrote:

> Some MTAs make smart decisions based on the 'from' envelope (i.e. msmtp)

So my first thought was "how in the world is this different from setting
the envelope sender?"

Reading the code, it seems:

> -	$raw_from = $envelope_sender if (defined $envelope_sender);
> +	if (defined $envelope_sender) {
> +		$raw_from = $envelope_sender;
> +		$envelope_from = 1;
> +	}
>  	$raw_from = extract_valid_address($raw_from);
>  	unshift (@sendmail_parameters,
> -			'-f', $raw_from) if(defined $envelope_sender);
> +			'-f', $raw_from) if(defined $envelope_from);

that this is a boolean to mean "use the from address as the envelope
sender".

It was of course all the more confusing for not being documented at all,
but even if documented, --envelope-from is IMHO confusingly similar to
--envelope-sender. Maybe --use-from-in-envelope would be a better name?

And of course, your patch is missing docs and tests.

-Peff

^ permalink raw reply

* [PATCH/RFC 3/3] git rerere unresolve file...
From: Johannes Sixt @ 2009-11-21 19:02 UTC (permalink / raw)
  To: git
In-Reply-To: <200911212001.06207.j6t@kdbg.org>

There was no way to remove a recorded resolution short of removing the
entire .git/rr-cache. This gets in the way when an incorrect resolution
was recorded.

This implements the subcommand 'git rerere unresolve' that selectively
removes the recorded resolution of the specified files. It also reverts
the resolution so that the files again have conflict markers. However,
these unresolved conflict markers not necessarily reflect "ours" and
"theirs" correctly because the preimage that was stored in the cache has
the conflicted sides in a canonical order.

In handle_file(), the checks for the beginning and end of a conflict
region have to be loosened slightly -- there can be any whitespace,
including a LF, not just a blank -- because after the conflict regions are
restored, there are no trailing blanks and a subsequent 'git rerere' would
not recognize them anymore.

'git checkout --conflict=merge path...' can restore the conflicted file
as well, but it does not remove the recorded resolution.

Signed-off-by: Johannes Sixt <j6t@kdbg.org>
---
 Documentation/git-rerere.txt |   10 +++++-
 builtin-rerere.c             |    9 +++--
 rerere.c                     |   74 ++++++++++++++++++++++++++++++++++++++----
 rerere.h                     |    2 +
 4 files changed, 84 insertions(+), 11 deletions(-)

diff --git a/Documentation/git-rerere.txt b/Documentation/git-rerere.txt
index 7dd515b..c9bf3f1 100644
--- a/Documentation/git-rerere.txt
+++ b/Documentation/git-rerere.txt
@@ -7,7 +7,7 @@ git-rerere - Reuse recorded resolution of conflicted merges
 
 SYNOPSIS
 --------
-'git rerere' ['clear'|'diff'|'status'|'gc']
+'git rerere' ['clear'|'diff'|'status'|'unresolve file...'|'gc']
 
 DESCRIPTION
 -----------
@@ -52,6 +52,14 @@ conflicts.  Additional arguments are passed directly to the system
 Like 'diff', but this only prints the filenames that will be tracked
 for resolutions.
 
+'unresolve'::
+
+Removes the resolution that was recorded for the specified files.
+The conflict sections are restored as well, although the direction of
+the "ours" and "theirs" sections may be inverted.
+You can use 'git checkout --conflict=merge file' to restore the
+original conflict markers in the correct direction.
+
 'gc'::
 
 This prunes records of conflicted merges that
diff --git a/builtin-rerere.c b/builtin-rerere.c
index 275827d..5d3a3a5 100644
--- a/builtin-rerere.c
+++ b/builtin-rerere.c
@@ -7,7 +7,7 @@
 #include "xdiff-interface.h"
 
 static const char git_rerere_usage[] =
-"git rerere [clear | status | diff | gc]";
+"git rerere [clear | status | diff | unresolve file... | gc]";
 
 /* these values are days */
 static int cutoff_noresolve = 15;
@@ -102,7 +102,7 @@ int cmd_rerere(int argc, const char **argv, const char *prefix)
 {
 	struct string_list merge_rr = { NULL, 0, 0, 1 };
 	struct string_list merge_rr_done = { NULL, 0, 0, 1 };
-	int i, fd;
+	int i, fd, ret = 0;
 
 	if (argc < 2)
 		return rerere();
@@ -129,10 +129,13 @@ int cmd_rerere(int argc, const char **argv, const char *prefix)
 			const char *name = (const char *)merge_rr.items[i].util;
 			diff_two(rerere_path(name, "preimage"), path, path, path);
 		}
+	else if (!strcmp(argv[1], "unresolve"))
+		ret = unresolve_rerere(&merge_rr, &merge_rr_done,
+				       get_pathspec(prefix, &argv[2]), fd);
 	else
 		usage(git_rerere_usage);
 
 	string_list_clear(&merge_rr, 1);
 	string_list_clear(&merge_rr_done, 1);
-	return 0;
+	return ret;
 }
diff --git a/rerere.c b/rerere.c
index 11fef88..b31008d 100644
--- a/rerere.c
+++ b/rerere.c
@@ -140,7 +140,7 @@ static int handle_file(const char *path,
 		git_SHA1_Init(&ctx);
 
 	while (fgets(buf, sizeof(buf), f)) {
-		if (!prefixcmp(buf, "<<<<<<< ")) {
+		if (!prefixcmp(buf, "<<<<<<<") && isspace(buf[7])) {
 			if (hunk != RR_CONTEXT)
 				goto bad;
 			hunk = RR_SIDE_1;
@@ -152,7 +152,7 @@ static int handle_file(const char *path,
 			if (hunk != RR_SIDE_1 && hunk != RR_ORIGINAL)
 				goto bad;
 			hunk = RR_SIDE_2;
-		} else if (!prefixcmp(buf, ">>>>>>> ")) {
+		} else if (!prefixcmp(buf, ">>>>>>>") && isspace(buf[7])) {
 			if (hunk != RR_SIDE_2)
 				goto bad;
 			if (strbuf_cmp(&one, &two) > 0)
@@ -248,23 +248,29 @@ static int record_preimage(struct string_list *rr, const char *path, int 
force)
 	return 0;
 }
 
-static int merge(const char *name, const char *path)
+#define RESOLVE 0
+#define UNRESOLVE 1
+#define UNRESOLVE_CHECK 2
+
+static int merge(const char *name, const char *path, int mode)
 {
 	int ret;
 	mmfile_t cur, base, other;
 	mmbuffer_t result = {NULL, 0};
 	xpparam_t xpp = {XDF_NEED_MINIMAL};
+	const char *basename = mode == RESOLVE ? "preimage" : "postimage";
+	const char *othername = mode == RESOLVE ? "postimage" : "preimage";
 
 	if (handle_file(path, NULL, rerere_path(name, "thisimage")) < 0)
 		return 1;
 
 	if (read_mmfile(&cur, rerere_path(name, "thisimage")) ||
-			read_mmfile(&base, rerere_path(name, "preimage")) ||
-			read_mmfile(&other, rerere_path(name, "postimage")))
+			read_mmfile(&base, rerere_path(name, basename)) ||
+			read_mmfile(&other, rerere_path(name, othername)))
 		return 1;
 	ret = xdl_merge(&base, &cur, "", &other, "",
 			&xpp, XDL_MERGE_ZEALOUS, &result);
-	if (!ret) {
+	if (!ret && mode != UNRESOLVE_CHECK) {
 		FILE *f = fopen(path, "w");
 		if (!f)
 			return error("Could not open %s: %s", path,
@@ -347,7 +353,7 @@ static int do_plain_rerere(struct string_list *rr,
 		const char *name = (const char *)rr->items[i].util;
 
 		if (has_rerere_resolution(name)) {
-			if (!merge(name, path)) {
+			if (!merge(name, path, RESOLVE)) {
 				if (rerere_autoupdate)
 					string_list_insert(path, &update);
 				fprintf(stderr,
@@ -433,3 +439,57 @@ int rerere(void)
 		return 0;
 	return do_plain_rerere(&merge_rr, &merge_rr_done, fd);
 }
+
+static int unresolve_check(struct string_list *rr_done, const char *path)
+{
+	struct string_list_item *item = string_list_lookup(path, rr_done);
+
+	if (!item) {
+		warning("not resolved using a previous resolution: %s", path);
+		return 0;
+	}
+	if (!has_rerere_resolution(item->util))
+		return error("no resolution found for %s", path);
+	if (merge(item->util, path, UNRESOLVE_CHECK))
+		return error("cannot revert resolution of %s", path);
+	return 0;
+}
+
+int unresolve_rerere_1(struct string_list *rr, struct string_list *rr_done,
+		       const char *path)
+{
+	struct string_list_item *item = string_list_lookup(path, rr_done);
+
+	if (!item)
+		return 0;
+	if (merge(item->util, path, UNRESOLVE))
+		return -1;
+
+	if (record_preimage(rr, path, 1))
+		return error("no conflict markers found: %s", path);
+
+	item->util = NULL;
+	unlink_or_warn(rerere_path(item->util, "postimage"));
+	return 0;
+}
+
+int unresolve_rerere(struct string_list *rr, struct string_list *rr_done,
+		     const char **pathspec, int fd)
+{
+	int i, ret = 0;
+
+	if (!pathspec)
+		return error("unresolve what?");
+
+	for (i = 0; pathspec[i]; i++) {
+		ret |= unresolve_check(rr_done, pathspec[i]);
+	}
+	if (ret)
+		return ret;
+
+	for (i = 0; !ret && pathspec[i]; i++) {
+		ret = unresolve_rerere_1(rr, rr_done, pathspec[i]);
+	}
+	ret |= write_rr(rr, rr_done, fd);
+	return ret;
+}
diff --git a/rerere.h b/rerere.h
index 9bb2f13..a0fa50f 100644
--- a/rerere.h
+++ b/rerere.h
@@ -7,5 +7,7 @@ extern int setup_rerere(struct string_list *, struct string_list *);
 extern int rerere(void);
 extern const char *rerere_path(const char *hex, const char *file);
 extern int has_rerere_resolution(const char *hex);
+extern int unresolve_rerere(struct string_list *, struct string_list *,
+	const char **, int);
 
 #endif
-- 
1.6.5.2.182.ge039a

^ permalink raw reply related

* [PATCH/RFC 2/3] rerere: make recording of the preimage reusable
From: Johannes Sixt @ 2009-11-21 19:01 UTC (permalink / raw)
  To: git
In-Reply-To: <200911212000.19326.j6t@kdbg.org>

This factors the code that computes the conflict hash and records the
preimage into a helper function.

Signed-off-by: Johannes Sixt <j6t@kdbg.org>
---
 rerere.c |   30 ++++++++++++++++++++----------
 1 files changed, 20 insertions(+), 10 deletions(-)

diff --git a/rerere.c b/rerere.c
index 84d0bb7..11fef88 100644
--- a/rerere.c
+++ b/rerere.c
@@ -229,6 +229,25 @@ static int find_conflict(struct string_list *conflict)
 	return 0;
 }
 
+static int record_preimage(struct string_list *rr, const char *path, int force)
+{
+	unsigned char sha1[20];
+	char *hex;
+	int ret;
+
+	ret = handle_file(path, sha1, NULL);
+	if (ret < 1)
+		return -1;
+
+	hex = xstrdup(sha1_to_hex(sha1));
+	string_list_insert(path, rr)->util = hex;
+	if (mkdir(git_path("rr-cache/%s", hex), 0755) && !force)
+		return -1;
+
+	handle_file(path, NULL, rerere_path(hex, "preimage"));
+	return 0;
+}
+
 static int merge(const char *name, const char *path)
 {
 	int ret;
@@ -310,17 +329,8 @@ static int do_plain_rerere(struct string_list *rr,
 	for (i = 0; i < conflict.nr; i++) {
 		const char *path = conflict.items[i].string;
 		if (!string_list_has_string(rr, path)) {
-			unsigned char sha1[20];
-			char *hex;
-			int ret;
-			ret = handle_file(path, sha1, NULL);
-			if (ret < 1)
-				continue;
-			hex = xstrdup(sha1_to_hex(sha1));
-			string_list_insert(path, rr)->util = hex;
-			if (mkdir(git_path("rr-cache/%s", hex), 0755))
+			if (record_preimage(rr, path, 0))
 				continue;
-			handle_file(path, NULL, rerere_path(hex, "preimage"));
 			fprintf(stderr, "Recorded preimage for '%s'\n", path);
 		}
 	}
-- 
1.6.5.2.182.ge039a

^ permalink raw reply related

* [PATCH/RFC 1/3] rerere: keep a list of resolved files in MERGE_RR
From: Johannes Sixt @ 2009-11-21 19:00 UTC (permalink / raw)
  To: git
In-Reply-To: <200911211958.40872.j6t@kdbg.org>

Previously, MERGE_RR entries that rerere detected as resolved were removed
from MERGE_RR so that it contained only entries for files that still had
conflicts.

This changes the "database" format to also keep the entries about files
for which resolutions have been recorded. The purpose is to allow that
resolved conflicts can be unresolved. To do that it is necessary to have
a mapping from the file name to the conflict hash.

The new format of MERGE_RR is:

1. Entries about unresolved conflicts.
2. An all-zeros SHA1 as boundary marker.
3. Entries about resolved conflicts.

Signed-off-by: Johannes Sixt <j6t@kdbg.org>
---
 builtin-rerere.c |    4 +++-
 rerere.c         |   49 ++++++++++++++++++++++++++++++++++++++++---------
 rerere.h         |    2 +-
 3 files changed, 44 insertions(+), 11 deletions(-)

diff --git a/builtin-rerere.c b/builtin-rerere.c
index adfb7b5..275827d 100644
--- a/builtin-rerere.c
+++ b/builtin-rerere.c
@@ -101,12 +101,13 @@ static int diff_two(const char *file1, const char *label1,
 int cmd_rerere(int argc, const char **argv, const char *prefix)
 {
 	struct string_list merge_rr = { NULL, 0, 0, 1 };
+	struct string_list merge_rr_done = { NULL, 0, 0, 1 };
 	int i, fd;
 
 	if (argc < 2)
 		return rerere();
 
-	fd = setup_rerere(&merge_rr);
+	fd = setup_rerere(&merge_rr, &merge_rr_done);
 	if (fd < 0)
 		return 0;
 
@@ -132,5 +133,6 @@ int cmd_rerere(int argc, const char **argv, const char *prefix)
 		usage(git_rerere_usage);
 
 	string_list_clear(&merge_rr, 1);
+	string_list_clear(&merge_rr_done, 1);
 	return 0;
 }
diff --git a/rerere.c b/rerere.c
index 29f95f6..84d0bb7 100644
--- a/rerere.c
+++ b/rerere.c
@@ -23,8 +23,20 @@ int has_rerere_resolution(const char *hex)
 	return !stat(rerere_path(hex, "postimage"), &st);
 }
 
-static void read_rr(struct string_list *rr)
+/*
+ * If MERGE_RR is read and rewritten by an old version, the section bound
+ * would not be preserved, and file names from both sections would be
+ * interleaved. We must make sure that the section marker does not end up
+ * in an arbitrary position. In particular, the safest result is that all
+ * paths are now in the first ("not done") section. Therefore, we choose
+ * a file name that sorts last (for all practical purposes).
+ */
+static const char section_mark[] =
+	"0000000000000000000000000000000000000000\t\377\377\377\377";
+
+static void read_rr(struct string_list *rr, struct string_list *rr_done)
 {
+	struct string_list *section = rr;
 	unsigned char sha1[20];
 	char buf[PATH_MAX];
 	FILE *in = fopen(merge_rr_path, "r");
@@ -43,14 +55,19 @@ static void read_rr(struct string_list *rr)
 			; /* do nothing */
 		if (i == sizeof(buf))
 			die("filename too long");
-		string_list_insert(buf, rr)->util = name;
+		if (prefixcmp(section_mark, name)) {
+			string_list_insert(buf, section)->util = name;
+		} else {
+			free(name);
+			section = rr_done;
+		}
 	}
 	fclose(in);
 }
 
 static struct lock_file write_lock;
 
-static int write_rr(struct string_list *rr, int out_fd)
+static void write_rr_section(struct string_list *rr, int out_fd)
 {
 	int i;
 	for (i = 0; i < rr->nr; i++) {
@@ -65,6 +82,17 @@ static int write_rr(struct string_list *rr, int out_fd)
 		    write_in_full(out_fd, path, length) != length)
 			die("unable to write rerere record");
 	}
+}
+
+static int write_rr(struct string_list *rr,
+		    struct string_list *rr_done, int out_fd)
+{
+	int length = strlen(section_mark)+1;
+
+	write_rr_section(rr, out_fd);
+	if (write_in_full(out_fd, section_mark, length) != length)
+		die("unable to write rerere record");
+	write_rr_section(rr_done, out_fd);
 	if (commit_lock_file(&write_lock) != 0)
 		die("unable to write rerere record");
 	return 0;
@@ -263,7 +291,8 @@ static int update_paths(struct string_list *update)
 	return status;
 }
 
-static int do_plain_rerere(struct string_list *rr, int fd)
+static int do_plain_rerere(struct string_list *rr,
+			   struct string_list *rr_done, int fd)
 {
 	struct string_list conflict = { NULL, 0, 0, 1 };
 	struct string_list update = { NULL, 0, 0, 1 };
@@ -328,13 +357,14 @@ static int do_plain_rerere(struct string_list *rr, int fd)
 		fprintf(stderr, "Recorded resolution for '%s'.\n", path);
 		copy_file(rerere_path(name, "postimage"), path, 0666);
 	mark_resolved:
+		string_list_insert(path, rr_done)->util = rr->items[i].util;
 		rr->items[i].util = NULL;
 	}
 
 	if (update.nr)
 		update_paths(&update);
 
-	return write_rr(rr, fd);
+	return write_rr(rr, rr_done, fd);
 }
 
 static int git_rerere_config(const char *var, const char *value, void *cb)
@@ -367,7 +397,7 @@ static int is_rerere_enabled(void)
 	return 1;
 }
 
-int setup_rerere(struct string_list *merge_rr)
+int setup_rerere(struct string_list *merge_rr, struct string_list *merge_rr_done)
 {
 	int fd;
 
@@ -378,17 +408,18 @@ int setup_rerere(struct string_list *merge_rr)
 	merge_rr_path = git_pathdup("MERGE_RR");
 	fd = hold_lock_file_for_update(&write_lock, merge_rr_path,
 				       LOCK_DIE_ON_ERROR);
-	read_rr(merge_rr);
+	read_rr(merge_rr, merge_rr_done);
 	return fd;
 }
 
 int rerere(void)
 {
 	struct string_list merge_rr = { NULL, 0, 0, 1 };
+	struct string_list merge_rr_done = { NULL, 0, 0, 1 };
 	int fd;
 
-	fd = setup_rerere(&merge_rr);
+	fd = setup_rerere(&merge_rr, &merge_rr_done);
 	if (fd < 0)
 		return 0;
-	return do_plain_rerere(&merge_rr, fd);
+	return do_plain_rerere(&merge_rr, &merge_rr_done, fd);
 }
diff --git a/rerere.h b/rerere.h
index 13313f3..9bb2f13 100644
--- a/rerere.h
+++ b/rerere.h
@@ -3,7 +3,7 @@
 
 #include "string-list.h"
 
-extern int setup_rerere(struct string_list *);
+extern int setup_rerere(struct string_list *, struct string_list *);
 extern int rerere(void);
 extern const char *rerere_path(const char *hex, const char *file);
 extern int has_rerere_resolution(const char *hex);
-- 
1.6.5.2.182.ge039a

^ permalink raw reply related

* [PATCH/RFC 0/3] git rerere unresolve file
From: Johannes Sixt @ 2009-11-21 18:58 UTC (permalink / raw)
  To: git

When you commit an incorrect conflict resolution, git rerere gets in the way: 
rerere clear only clears cache entries of not yet resolved conflicts. But 
there is no other way to remove an incorrect resolution short of purging the 
whole rr-cache.

This series implements 'git rerere unresolve' that removes a recorded 
resolution.

This is RFC for two reasons:

- It changes the contents of MERGE_RR in a way that *may* interfer in unwanted 
ways with older versions that do not understand unresolve.

- rerere unresolve also restores the conflict regions. I'm not sure whether 
this is good because there is 'git checkout --conflict=merge file' that does 
it in a better way. See the commit message of patch 3.

If rerere unresolve does *not* restore conflict regions (and record the result 
as preimage right away) we are facing a problem: When the resolution is 
committed, the postimage has differences from the preimage that are not 
related to the conflict. This may inhibit reusing the resolution later when 
the file has new changes.

Johannes Sixt (3):
  rerere: keep a list of resolved files in MERGE_RR
  rerere: make recording of the preimage reusable
  git rerere unresolve file...

 Documentation/git-rerere.txt |   10 +++-
 builtin-rerere.c             |   13 +++-
 rerere.c                     |  153 ++++++++++++++++++++++++++++++++++-------
 rerere.h                     |    4 +-
 4 files changed, 148 insertions(+), 32 deletions(-)

^ permalink raw reply

* Re: [PATCH] git-count-objects: Fix a disk-space under-estimate on Cygwin
From: Ramsay Jones @ 2009-11-21  0:00 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: GIT Mailing-list
In-Reply-To: <7vlji17i02.fsf@alter.siamese.dyndns.org>

Junio C Hamano wrote:
> When estimating the on-disk footprint of a file, we either used st_blocks
> that is counted in 512-byte blocks (traditional unix behaviour), or on
> platforms that do not have such st_blocks field in struct stat, simply the
> file size itself.  Building with NO_ST_BLOCKS_IN_STRUCT_STAT will choose
> the latter implementaion.
> 
> POSIX.1 says in its <sys/stat.h> description on this issue:
> 
>     The unit for the st_blocks member of the stat structure is not
>     defined within POSIX.1-2008. In some implementations it is 512
>     bytes. It may differ on a file system basis. There is no
>     correlation between values of the st_blocks and st_blksize,
>     and the f_bsize (from <sys/statvfs.h>) structure members.
> 
> Even though the above explicitly states st_blksize does not have any
> correlation, at least on one system (Cygwin on NTFS), the st_blocks field
> seems to count in blocks of st_blksize bytes.  A new Makefile variable
> ST_BLOCKS_COUNTS_IN_BLKSIZE chooses to use this for the on-disk footprint.

My first attempt to fix this problem was very similar to this. ;-)

BTW, I thought that st_blocks and st_blksize were both XSI/SUS extensions
and not part of POSIX, but your quote above contradicts that. Also, I don't
know that you can count on *both* fields always being present (I have not
personally used a system that didn't have st_blksize if it had st_blocks,
but I don't think it's guaranteed).

Anyway, I decided against this kind of solution because it didn't address
the problem of returning different answers depending on the setting of
core.filemode.

Having said that, maybe that's not a big deal; in everyday use I can't
imagine that anyone would change the core.filemode setting more than once,
if ever. (I *have* been doing that quite a bit while testing an msvc-built
git on cygwin; but again, that's probably *not* an everyday usage :-P )

I haven't tried this patch, but I think you may need to add something like
the following (*not tested*):

--- >8 ---
diff --git a/compat/cygwin.c b/compat/cygwin.c
index b4a51b9..7e9edec 100644
--- a/compat/cygwin.c
+++ b/compat/cygwin.c
@@ -53,6 +53,7 @@ static int do_stat(const char *file_name, struct stat *buf, stat_fn_t cygstat)
 		buf->st_size = (off_t)fdata.nFileSizeLow;
 #endif
 		buf->st_blocks = size_to_blocks(buf->st_size);
+		buf->st_blksize = 512;
 		filetime_to_timespec(&fdata.ftLastAccessTime, &buf->st_atim);
 		filetime_to_timespec(&fdata.ftLastWriteTime, &buf->st_mtim);
 		filetime_to_timespec(&fdata.ftCreationTime, &buf->st_ctim);
--- >8 ---

ATB,
Ramsay Jones

^ permalink raw reply related

* [PATCH v2] git-count-objects: Fix a disk-space under-estimate on Cygwin
From: Ramsay Jones @ 2009-11-20 23:27 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: GIT Mailing-list


On Cygwin, the st_blocks field in 'struct stat' counts in blocks
of st_blksize bytes. At least on NTFS, the st_blksize field is
not 512 bytes, as required by the code, which leads to an under
estimate of the disk-space used.

Setting the build variable NO_ST_BLOCKS_IN_STRUCT_STAT, switches
to an algorithm that only uses the st_size field to compute the
disk-space estimate.

Signed-off-by: Ramsay Jones <ramsay@ramsay1.demon.co.uk>
---

Changed since v1:
    - a commit message!
    - removed comment.

ATB,
Ramsay Jones

 Makefile |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/Makefile b/Makefile
index 5d5976f..8902dba 100644
--- a/Makefile
+++ b/Makefile
@@ -783,6 +783,7 @@ ifeq ($(uname_O),Cygwin)
 	NO_FAST_WORKING_DIRECTORY = UnfortunatelyYes
 	NO_TRUSTABLE_FILEMODE = UnfortunatelyYes
 	OLD_ICONV = UnfortunatelyYes
+	NO_ST_BLOCKS_IN_STRUCT_STAT = YesPlease
 	# There are conflicting reports about this.
 	# On some boxes NO_MMAP is needed, and not so elsewhere.
 	# Try commenting this out if you suspect MMAP is more efficient
-- 
1.6.5

^ permalink raw reply related

* Re: How to make git diff-* ignore some patterns?
From: Björn Steinbrink @ 2009-11-21 18:07 UTC (permalink / raw)
  To: Dirk Süsserott; +Cc: Git Mailing List
In-Reply-To: <4B0817EE.1040000@dirk.my1.cc>

On 2009.11.21 17:40:14 +0100, Dirk Süsserott wrote:
> is there a way to tell "git diff-index" to ignore some special
> patterns, such that /^-- Dump completed on .*$/ is NOT recognized as
> a difference and "git diff-index" returns 0 if that's the only
> difference?

If you don't mind losing that line, you could use a clean filter via
.gitattributes:

echo '*.sql filter=mysql_dump' >> .gitattributes
git config filter.mysql_dump.clean "sed -e '/^-- Dump completed on .*$/d'"

That way, git will filter all *.sql paths through that sed command
before storing them as blobs, dropping that "Dump completed" line from
the data stored in the repo.

Björn

^ permalink raw reply

* Re: Git graph with branch labels for all paths in text environment
From: Jonas Fonseca @ 2009-11-21 17:50 UTC (permalink / raw)
  To: rhlee; +Cc: git
In-Reply-To: <1258373038892-4011651.post@n2.nabble.com>

On Mon, Nov 16, 2009 at 07:03, rhlee <richard@webdezign.co.uk> wrote:
> Is there anyway to to view a text based git grah that shows all paths with
> the branch labels? Like a on gitk but ncurses based?
>
> [...]
> I can get all branch labels in tig, but only for the current branch.

You can browse all branches by using: tig --all
However, the graph drawing is rather poor for complex git histories.

-- 
Jonas Fonseca

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox