Git development
 help / color / mirror / Atom feed
* Re: [PATCH] builtin-apply.c: Skip filenames without enough components
From: Andreas Gruenbacher @ 2010-01-17  2:44 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git
In-Reply-To: <7vr5ppa2st.fsf@alter.siamese.dyndns.org>

On Sunday 17 January 2010 03:22:10 am Junio C Hamano wrote:
> Tests?

Sure if you think it's worth a regression test ... "git apply -p2" of the 
following patch fails with "fatal: git diff header lacks filename information 
when removing 2 leading pathname components (line 6)" with the fix, and 
creates b/f without:

	diff --git a/f b/f
	new file mode 100644
	index 0000000..6a69f92
	--- /dev/null
	+++ b/f
	@@ -0,0 +1 @@
	+f

(Some earlier versions of git failed with "fatal: git apply: bad git-diff - 
inconsistent new filename on line 5" in this case.)

Andreas

^ permalink raw reply

* What's cooking in git.git (Jan 2010, #05; Sat, 16)
From: Junio C Hamano @ 2010-01-17  2:46 UTC (permalink / raw)
  To: git

Here are the topics that have been cooking.  Commits prefixed with '-' are
only in 'pu' while commits prefixed with '+' are in 'next'.  The ones
marked with '.' do not appear in any of the integration branches, but I am
still holding onto them.

I am expecting that the next week we will see quite a busy 'master', as I
would really like to close the merge window for 1.7.0 and tag -rc0 by the
end of it.

--------------------------------------------------
[New Topics]

* dp/maint-1.6.5-fast-import-non-commit-tag (2010-01-14) 1 commit
  (merged to 'next' on 2010-01-16 at f95ea8e)
 + fast-import: tag may point to any object type

* il/push-set-upstream (2010-01-16) 1 commit
  (merged to 'next' on 2010-01-16 at e3a7a60)
 + Add push --set-upstream

* js/windows (2010-01-15) 7 commits
 - Do not use date.c:tm_to_time_t() from compat/mingw.c
 - MSVC: Windows-native implementation for subset of Pthreads API
 - MSVC: Fix an "incompatible pointer types" compiler warning
 - Windows: avoid the "dup dance" when spawning a child process
 - Windows: simplify the pipe(2) implementation
 - Windows: boost startup by avoiding a static dependency on shell32.dll
 - Windows: disable Python

* nd/status-partial-refresh (2010-01-14) 1 commit
  (merged to 'next' on 2010-01-16 at f77bc8f)
 + status: only touch path we may need to check

* rr/core-tutorial (2010-01-16) 1 commit
  (merged to 'next' on 2010-01-16 at d9dd8bd)
 + Documentation: Update git core tutorial clarifying reference to scripts

* jc/conflict-mark-len-attr (2010-01-16) 3 commits
 . WIP : honor conflict-marker-lenght in rerere (does not work yet)
 . rerere: use ll_merge() instead of using xdl_merge()
 . conflict-marker-length: new attribute
 (this branch uses jc/cache-unmerge.)

I am attempting to introduce a new per-path attribute to specify
non-default conflict marker length to help rerere grok conflicts in
Documentation/git-merge.txt, but the series is not yet in a presentable
state yet.

--------------------------------------------------
[Stalled]

* ap/merge-backend-opts (2008-07-18) 6 commits
 - Document that merge strategies can now take their own options
 - Extend merge-subtree tests to test -Xsubtree=dir.
 - Make "subtree" part more orthogonal to the rest of merge-recursive.
 - Teach git-pull to pass -X<option> to git-merge
 - git merge -X<option>
 - git-merge-file --ours, --theirs

"git pull" patch needs sq-then-eval fix to protect it from $IFS
but otherwise seemed good.

* js/refer-upstream (2009-09-10) 1 commit
 - Introduce <branch>@{upstream} notation

This does not teach the public interface about the new syntax; callers
that care about distinction between name vs SHA-1 might not work as well
as they should.

* jh/notes (2009-12-07) 11 commits
 - Refactor notes concatenation into a flexible interface for combining notes
 - Notes API: Allow multiple concurrent notes trees with new struct notes_tree
 - Notes API: for_each_note(): Traverse the entire notes tree with a callback
 - Notes API: get_note(): Return the note annotating the given object
 - Notes API: add_note(): Add note objects to the internal notes tree structure
 - Notes API: init_notes(): Initialize the notes tree from the given notes ref
 - Notes API: get_commit_notes() -> format_note() + remove the commit restriction
 - Minor style fixes to notes.c
  (merged to 'next' on 2010-01-02 at ae42130)
 + Add more testcases to test fast-import of notes
 + Rename t9301 to t9350, to make room for more fast-import tests
 + fast-import: Proper notes tree manipulation

http://thread.gmane.org/gmane.comp.version-control.git/134738

What's the status of the fourth and later patches on this topic?  Overall
it looked reasonable, if I recall correctly what I thought when I reviewed
it last time, and I am tempted to merge it to 'next' soonish.  Please
file complaints before I do so if people have objections.

Hold: JH on 2010-01-05, http://article.gmane.org/gmane.comp.version-control.git/136183

--------------------------------------------------
[Will merge to 'master' soon unless somebody complains]

* jk/warn-author-committer-after-commit (2010-01-13) 4 commits
  (merged to 'next' on 2010-01-16 at f22c077)
 + commit: allow suppression of implicit identity advice
 + commit: show interesting ident information in summary
 + strbuf: add strbuf_addbuf_percentquote
 + strbuf_expand: convert "%%" to "%"

* tr/http-push-ref-status (2010-01-08) 6 commits
  (merged to 'next' on 2010-01-16 at 7e872ac)
 + transport-helper.c::push_refs(): emit "no refs" error message
 + transport-helper.c::push_refs(): ignore helper-reported status if ref is not to be pushed
 + transport.c::transport_push(): make ref status affect return value
 + refactor ref status logic for pushing
 + t5541-http-push.sh: add test for unmatched, non-fast-forwarded refs
 + t5541-http-push.sh: add tests for non-fast-forward pushes

* sr/gfi-options (2009-12-04) 7 commits
  (merged to 'next' on 2010-01-10 at 8b305fb)
 + fast-import: add (non-)relative-marks feature
 + fast-import: allow for multiple --import-marks= arguments
 + fast-import: test the new option command
 + fast-import: add option command
 + fast-import: add feature command
 + fast-import: put marks reading in its own function
 + fast-import: put option parsing code in separate functions

* tc/smart-http-restrict (2010-01-14) 5 commits
  (merged to 'next' on 2010-01-16 at 71fc84c)
 + Test t5560: Fix test when run with dash
  (merged to 'next' on 2010-01-06 at 82736cb)
 + Smart-http tests: Test http-backend without curl or a webserver
 + Smart-http tests: Break test t5560-http-backend into pieces
 + Smart-http tests: Improve coverage in test t5560
 + Smart-http: check if repository is OK to export before serving it

* tc/clone-v-progress (2009-12-26) 4 commits
  (merged to 'next' on 2010-01-10 at ec2bfd7)
 + clone: use --progress to force progress reporting
 + clone: set transport->verbose when -v/--verbose is used
 + git-clone.txt: reword description of progress behaviour
 + check stderr with isatty() instead of stdout when deciding to show progress

Perhaps needs an entry in the Release Notes, but otherwise looked Ok.

* jk/run-command-use-shell (2010-01-01) 8 commits
  (merged to 'next' on 2010-01-10 at 7479e2a)
 + t4030, t4031: work around bogus MSYS bash path conversion
 + diff: run external diff helper with shell
 + textconv: use shell to run helper
 + editor: use run_command's shell feature
 + run-command: optimize out useless shell calls
 + run-command: convert simple callsites to use_shell
 + t0021: use $SHELL_PATH for the filter script
 + run-command: add "use shell" option

Shuffled the commits in the topic, following J6t's suggestion in
http://thread.gmane.org/gmane.comp.version-control.git/136128

* jn/makefile (2010-01-06) 4 commits
  (merged to 'next' on 2010-01-10 at f5a5d42)
 + Makefile: consolidate .FORCE-* targets
 + Makefile: learn to generate listings for targets requiring special flags
 + Makefile: use target-specific variable to pass flags to cc
 + Makefile: regenerate assembler listings when asked

* jc/maint-1.6.1-checkout-m-custom-merge (2010-01-06) 1 commit
  (merged to 'next' on 2010-01-10 at df14116)
 + checkout -m path: fix recreating conflicts

* bk/fix-relative-gitdir-file (2010-01-08) 2 commits
  (merged to 'next' on 2010-01-16 at cc4ae57)
 + Handle relative paths in submodule .git files
 + Test update-index for a gitlink to a .git file

* jh/commit-status (2010-01-13) 2 commits
  (merged to 'next' on 2010-01-13 at 0905d59)
 + t7502: test commit.status, --status and --no-status
 + commit: support commit.status, --status, and --no-status

I have already given ample time for people to react, but ended up getting
tired of waiting for tests to materialize and doing it myself, as I want
to close merge window for 1.7.0-rc0 by the end of next week to have the
final release early next month.

* sd/cd-p-show-toplevel (2010-01-12) 2 commits
  (merged to 'next' on 2010-01-16 at 57d6d31)
 + Use $(git rev-parse --show-toplevel) in cd_to_toplevel().
 + Add 'git rev-parse --show-toplevel' option.

Avoid having to use "cd -P" that may not be available on some platforms'
shells.

* tc/test-locate-httpd (2010-01-02) 1 commit
  (merged to 'next' on 2010-01-06 at 9d913e5)
 + t/lib-http.sh: Restructure finding of default httpd location

--------------------------------------------------
[Will merge to 'master' after a bit more cooking in 'next']

* mh/rebase-fixup (2010-01-14) 21 commits
  (merged to 'next' on 2010-01-16 at 7ccb228)
 + rebase -i: Retain user-edited commit messages after squash/fixup conflicts
 + t3404: Set up more of the test repo in the "setup" step
 + rebase -i: For fixup commands without squashes, do not start editor
 + rebase -i: Change function make_squash_message into update_squash_message
 + rebase -i: Extract function do_with_author
 + rebase -i: Handle the author script all in one place in do_next
 + rebase -i: Extract a function "commit_message"
 + rebase -i: Simplify commit counting for generated commit messages
 + rebase -i: Improve consistency of commit count in generated commit messages
 + t3404: Test the commit count in commit messages generated by "rebase -i"
 + rebase -i: Introduce a constant AMEND
 + rebase -i: Introduce a constant AUTHOR_SCRIPT
 + rebase -i: Document how temporary files are used
 + rebase -i: Use symbolic constant $MSG consistently
 + rebase -i: Use "test -n" instead of "test ! -z"
 + rebase -i: Inline expression
 + rebase -i: Remove dead code
 + rebase -i: Make the condition for an "if" more transparent
  (merged to 'next' on 2010-01-12 at e84eab0)
 + rebase-i: Ignore comments and blank lines in peek_next_command
 + lib-rebase: Allow comments and blank lines to be added to the rebase script
 + lib-rebase: Provide clearer debugging info about what the editor did
 + Add a command "fixup" to rebase --interactive
 + t3404: Use test_commit to set up test repository
 (this branch is used by ns/rebase-auto-squash.)

* ns/rebase-auto-squash (2009-12-08) 1 commit
  (merged to 'next' on 2010-01-06 at da4e2f5)
 + rebase -i --autosquash: auto-squash commits
 (this branch uses mh/rebase-fixup.)

* da/difftool (2010-01-15) 10 commits
  (merged to 'next' on 2010-01-16 at 609f0da)
 + difftool: Update copyright notices to list each year separately
 + difftool: Use eval to expand '--extcmd' expressions
 + difftool: Add '-x' and as an alias for '--extcmd'
 + t7800-difftool.sh: Simplify the --extcmd test
  (merged to 'next' on 2010-01-10 at 749c870)
 + git-diff.txt: Link to git-difftool
 + difftool: Allow specifying unconfigured commands with --extcmd
 + difftool--helper: Remove use of the GIT_MERGE_TOOL variable
 + difftool--helper: Update copyright and remove distracting comments
  (merged to 'next' on 2010-01-06 at e957395)
 + git-difftool: Add '--gui' for selecting a GUI tool
 + t7800-difftool: Set a bogus tool for use by tests

* mm/conflict-advice (2010-01-12) 1 commit
  (merged to 'next' on 2010-01-16 at b83be11)
 + Be more user-friendly when refusing to do something because of conflict.

* jc/maint-strbuf-add-fix-doubling (2010-01-12) 1 commit
  (merged to 'next' on 2010-01-16 at 5959eee)
 + strbuf_addbuf(): allow passing the same buf to dst and src

* jc/maint-1.6.4-grep-lookahead (2010-01-10) 1 commit
  (merged to 'next' on 2010-01-13 at 20f8f4b)
 + grep: optimize built-in grep by skipping lines that do not hit
 (this branch is used by jc/grep-lookahead and jc/maint-grep-lookahead.)

Optimize the "line-by-line" internal grep by skiping en masse over lines
that cannot possibly match.

* jc/maint-grep-lookahead (2010-01-12) 0 commits
 (this branch uses jc/maint-1.6.4-grep-lookahead; is used by jc/grep-lookahead.)

Early conflict resolution for the above for recent git.

* jc/grep-lookahead (2010-01-15) 4 commits
 - grep --no-index: allow use of "git grep" outside a git repository
 - grep: prepare to run outside of a work tree
  (merged to 'next' on 2010-01-13 at 20f8f4b)
 + grep: rip out pessimization to use fixmatch()
 + grep: rip out support for external grep
 (this branch uses jc/maint-1.6.4-grep-lookahead and jc/maint-grep-lookahead.)

* nd/include-termios-for-osol (2010-01-11) 1 commit
  (merged to 'next' on 2010-01-16 at 3160c76)
 + Add missing #include to support TIOCGWINSZ on Solaris

* pc/uninteresting-submodule-disappear-upon-switch-branches (2010-01-11) 1 commit
  (merged to 'next' on 2010-01-16 at b06ca1a)
 + Remove empty directories when checking out a commit with fewer submodules

Instead of using unlink(2) that will never succeed, use rmdir(2) to remove
an empty directory, knowing that this won't harm a populated directory.

* jl/submodule-diff (2010-01-16) 2 commits
  (merged to 'next' on 2010-01-16 at 0a99e3c)
 + Teach diff that modified submodule directory is dirty
 + Show submodules as modified when they contain a dirty work tree

* jc/ls-files-ignored-pathspec (2010-01-08) 4 commits
  (merged to 'next' on 2010-01-16 at d36016a)
 + ls-files: fix overeager pathspec optimization
 + read_directory(): further split treat_path()
 + read_directory_recursive(): refactor handling of a single path into a separate function
 + t3001: test ls-files -o ignored/dir

* js/exec-error-report (2010-01-12) 4 commits
  (merged to 'next' on 2010-01-16 at 0e28d02)
 + Improve error message when a transport helper was not found
 + start_command: detect execvp failures early
 + run-command: move wait_or_whine earlier
 + start_command: report child process setup errors to the parent's stderr

* jc/fix-tree-walk (2009-09-14) 7 commits
  (merged to 'next' on 2010-01-13 at 1c01b87)
 + read-tree --debug-unpack
 + unpack-trees.c: look ahead in the index
 + unpack-trees.c: prepare for looking ahead in the index
 + Aggressive three-way merge: fix D/F case
 + traverse_trees(): handle D/F conflict case sanely
 + more D/F conflict tests
 + tests: move convenience regexp to match object names to test-lib.sh

Resurrected from "Ejected" category.  This is fix for a tricky codepath
and testing and improving before it hits 'master' is greatly appreciated.
(I have been using this in my private build for some time).

* jc/cache-unmerge (2009-12-25) 9 commits
  (merged to 'next' on 2010-01-13 at 2290c44)
 + rerere forget path: forget recorded resolution
 + rerere: refactor rerere logic to make it independent from I/O
 + rerere: remove silly 1024-byte line limit
 + resolve-undo: teach "update-index --unresolve" to use resolve-undo info
 + resolve-undo: "checkout -m path" uses resolve-undo information
 + resolve-undo: allow plumbing to clear the information
 + resolve-undo: basic tests
 + resolve-undo: record resolved conflicts in a new index extension section
 + builtin-merge.c: use standard active_cache macros
 (this branch is used by jc/conflict-mark-len-attr.)

* jc/rerere (2009-12-04) 1 commit
  (merged to 'next' on 2010-01-10 at e295b7f)
 + Teach --[no-]rerere-autoupdate option to merge, revert and friends

--------------------------------------------------
[Cooking]

* jc/symbol-static (2010-01-11) 17 commits
 - symlinks.c: remove unused functions
 - object.c: remove unused functions
 - blob.c: remove unused function
 - strbuf.c: remove unused function
 - sha1_file.c: remove unused function
 - mailmap.c: remove unused function
 - utf8.c: mark file-local function static
 - submodule.c: mark file-local function static
 - quote.c: mark file-local function static
 - remote-curl.c: mark file-local function static
 - read-cache.c: mark file-local functions static
 - parse-options.c: mark file-local function static
 - entry.c: mark file-local function static
 - http.c: mark file-local functions static
 - pretty.c: mark file-local function static
 - builtin-rev-list.c: mark file-local function static
 - bisect.c: mark file-local function static

Mark file-local symbols "static", and remove unused functions.  Daniel
suggests to leave some comment for blob.c and I agree in principle, but
I don't think of a good description myself.

* jh/gitweb-cached (2010-01-13) 9 commits
 - gitweb: File based caching layer (from git.kernel.org)
 - gitweb: Convert output to using indirect file handle
 - gitweb: cleanup error message produced by undefined $site_header
 - gitweb: add a get function to compliment print_sort_th
 - gitweb: add a get function to compliment print_local_time
 - gitweb: Makefile improvements
 - gitweb: Add option to force version match
 - gitweb: change die_error to take "extra" argument for extended die information
 - gitweb: Load checking

Replaced with a re-roll.  Update to t9500 is probably needed.

* jc/ident (2010-01-08) 3 commits
 - ident.c: treat $EMAIL as giving user.email identity explicitly
  (merged to 'next' on 2010-01-10 at f1f9ded)
 + ident.c: check explicit identity for name and email separately
 + ident.c: remove unused variables

Opinions on the topmost one?

* jc/branch-d (2009-12-29) 1 commit
  (merged to 'next' on 2010-01-10 at 61a14b7)
 + branch -d: base the "already-merged" safety on the branch it merges with

^ permalink raw reply

* Re: Integration-Manager Workflow
From: Michael Poole @ 2010-01-17  2:53 UTC (permalink / raw)
  To: Adrián Ribao Martínez; +Cc: git
In-Reply-To: <201001162047.38010.aribao@gmail.com>

Adrián Ribao Martínez writes:

>> Adrián Ribao Martínez writes:
>> 
>> > What happens if they accidentally work in the develop branch instead of creating a new one? What should we do?
>> > I think I should never fetch from teamx.myserver.net to avoid this problem and instead track the branch like in step 2. Is this correct?
>> 
>> It is simpler than that.
>> 
>> If you just use "git remote add teamx teamx.myserver.net:/...." (rather
>> than cloning your integration repository from one of those
>> repositories), it will leave all your local branches alone -- any
>> changes to teamx.myserver.net's "develop" branch will only show up in
>> the teamx/develop tracking branch.
>
> I think this is a stupid question but, how do I bring the feature1 branch from teamx to my local repository?

In brief, "git fetch teamx" -- it will copy that repository's branches
into "tracking" branches.  In your repository, they will be named like
teamx/develop, teamx/test, teamx/feature, and so on.

When you run the "git remote add teamx ${location}" command, it creates
a section in .git/config that looks like this:

[remote "teamx"]
        url = ssh://teamx.myserver.net/home/teamx/product.git
        fetch = +refs/heads/*:refs/remotes/teamx/*

This tells git to copy the remote branches to tracking branches; it will
not overwrite any of your own branches.  You can later add "push"
entries to this section to change the default behavior for "git push
teamx".  For example, adding:

         push = refs/head/develop
         push = refs/head/test:refs/head/test
         push = +refs/head/master

These all tell git to push your local branch (develop, test or master)
to the same branch name in the teamx repository.  The + in the last line
says to push even when it is not a fast-forward.  (The "<refspec>"
section of the git-push man pages has more discussion of the syntax.
Using these push entries makes sure that you don't accidentally modify a
feature branch on the team's repository.)

>> 
>> The reason is that a fetch or pull only merges into your develop branch
>> if your branch.develop.merge git-config entry specifies an upstream
>> branch -- more detail can be found in the git-config man page under
>> branch.<name>.remote and branch.<name>.merge.
>> 
>> Those entries are set up when you clone from a repository, and through
>> some other commands, but if teamx clones from the integration server,
>> they can only mess up their own develop branch.  If/when you push into
>> teamx's repository from yours, you can forcibly overwrite any of those
>> accidental changes.  (Normally, though, the push would only do a
>> fast-forward merge -- so if teamx made such a mistake, the merge will
>> fail until you address the mismatch.)
>
> I'm not sure if I understand.

The process you listed looks workable, although I would swap 2 and 3 to
save commands when the change is good (with no extra commands if the
change is bad).  In addition, merging first will find merge conflicts
before you do any verification.

> 1. I bring the feature1 to my local repository.

git fetch teamx

> 2. Check if everything is ok

git checkout teamx/feature1
make clean test (or whatever is appropriate)

> 3. Merge or rebase the branch into develop

git checkout develop
git merge teamx/feature1

If I were to swap the two steps above, I would make sure I was on the
develop branch, and then run:
  git merge teamx/feature1
  make clean test
If the check-out fails, "git reset --hard HEAD^" will back up to the
first parent commit -- in this case, the previous tip commit for
"develop".  If the check passes, the rest of the process is the same.

> 4. Push the develop changes into the in central repository

git push central develop

> 5. Push and force the develop changes into the teamx server

git push teamx develop

> 6. The developers pull their local repositories from teamx server

git pull teamx

Hopefully this helps explain things.

Michael Poole

^ permalink raw reply

* Re: [PATCH] git status: display current branch name in color
From: Michael Wookey @ 2010-01-17  4:31 UTC (permalink / raw)
  To: Git Mailing List, Junio C Hamano
In-Reply-To: <d2e97e801001141823i7519864dy264488d36fca465c@mail.gmail.com>

> There is an existing highlight when the user is not on any branch.
> Enhance this functionality to always provide the name of the current
> branch in color.
>
> Signed-off-by: Michael Wookey <michaelwookey@gmail.com>
> ---
>  wt-status.c |   10 ++++++----
>  wt-status.h |    3 ++-
>  2 files changed, 8 insertions(+), 5 deletions(-)

Any thoughts on this?

I have found this to be a useful feature; especially when using
msysGit in a Windows CMD shell. Specifically because a CMD shell
provides no ability for any sort of "git-completion.bash" prompt. By
highlighting the current branch name, the colouring has helped to
quickly identify what the current branch is.

^ permalink raw reply

* [PATCH] cvsimport: update to use non-dash git commands
From: Ben Walton @ 2010-01-17  3:55 UTC (permalink / raw)
  To: git; +Cc: Ben Walton

The cvsimport module was using the old git subcommand calling
convention (eg: git-init) in several places.  Clean this up to use
only modern calling conventions and be internally consistent in how
commands are passed to system().

Reported-by: Alexander Maier <amaier@opencsw.org>
Signed-off-by: Ben Walton <bwalton@artsci.utoronto.ca>
---
 git-cvsimport.perl |   32 ++++++++++++++++----------------
 1 files changed, 16 insertions(+), 16 deletions(-)

diff --git a/git-cvsimport.perl b/git-cvsimport.perl
index a7d215c..39e5842 100755
--- a/git-cvsimport.perl
+++ b/git-cvsimport.perl
@@ -609,16 +609,16 @@ $orig_git_index = $ENV{GIT_INDEX_FILE} if exists $ENV{GIT_INDEX_FILE};
 my %index; # holds filenames of one index per branch
 
 unless (-d $git_dir) {
-	system("git-init");
+	system(qw(git init));
 	die "Cannot init the GIT db at $git_tree: $?\n" if $?;
-	system("git-read-tree");
+	system(qw(git read-tree));
 	die "Cannot init an empty tree: $?\n" if $?;
 
 	$last_branch = $opt_o;
 	$orig_branch = "";
 } else {
-	open(F, "git-symbolic-ref HEAD |") or
-		die "Cannot run git-symbolic-ref: $!\n";
+	open(F, "git symbolic-ref HEAD |") or
+		die "Cannot run git symbolic-ref: $!\n";
 	chomp ($last_branch = <F>);
 	$last_branch = basename($last_branch);
 	close(F);
@@ -761,9 +761,9 @@ sub commit {
 		$index{$branch} = tmpnam();
 		$ENV{GIT_INDEX_FILE} = $index{$branch};
 		if ($ancestor) {
-		    system("git-read-tree", "$remote/$ancestor");
+		    system(qw(git read-tree), "$remote/$ancestor");
 		} else {
-		    system("git-read-tree", "$remote/$branch");
+		    system(qw(git read-tree), "$remote/$branch");
 		}
 		die "read-tree failed: $?\n" if $?;
 	    }
@@ -822,7 +822,7 @@ sub commit {
 	waitpid($pid,0);
 	die "Error running git-commit-tree: $?\n" if $?;
 
-	system('git-update-ref', "$remote/$branch", $cid) == 0
+	system(qw(git update-ref), "$remote/$branch", $cid) == 0
 		or die "Cannot write branch $branch for update: $!\n";
 
 	if ($tag) {
@@ -832,7 +832,7 @@ sub commit {
 		$xtag =~ s/[\/]/$opt_s/g;
 		$xtag =~ s/\[//g;
 
-		system('git-tag', '-f', $xtag, $cid) == 0
+		system(qw(git tag -f), $xtag, $cid) == 0
 			or die "Cannot create tag $xtag: $!\n";
 
 		print "Created tag '$xtag' on '$branch'\n" if $opt_v;
@@ -993,7 +993,7 @@ while (<CVS>) {
 		}
 		commit();
 		if (($commitcount & 1023) == 0) {
-			system("git repack -a -d");
+			system(qw(git repack -a -d));
 		}
 		$state = 1;
 	} elsif ($state == 11 and /^-+$/) {
@@ -1017,7 +1017,7 @@ my $line = `git-count-objects`;
 if ($line =~ /^(\d+) objects, (\d+) kilobytes$/) {
   my ($n_objects, $kb) = ($1, $2);
   1024 < $kb
-    and system("git repack -a -d");
+    and system(qw(git repack -a -d));
 }
 
 foreach my $git_index (values %index) {
@@ -1042,24 +1042,24 @@ if ($orig_branch) {
 	if ($tip_at_start ne $tip_at_end) {
 		for ($tip_at_start, $tip_at_end) { chomp; }
 		print "Fetched into the current branch.\n" if $opt_v;
-		system(qw(git-read-tree -u -m),
+		system(qw(git read-tree -u -m),
 		       $tip_at_start, $tip_at_end);
 		die "Fast-forward update failed: $?\n" if $?;
 	}
 	else {
-		system(qw(git-merge cvsimport HEAD), "$remote/$opt_o");
+		system(qw(git merge cvsimport HEAD), "$remote/$opt_o");
 		die "Could not merge $opt_o into the current branch.\n" if $?;
 	}
 } else {
 	$orig_branch = "master";
 	print "DONE; creating $orig_branch branch\n" if $opt_v;
-	system("git-update-ref", "refs/heads/master", "$remote/$opt_o")
+	system(qw(git update-ref refs/heads/master), "$remote/$opt_o")
 		unless defined get_headref('refs/heads/master');
-	system("git-symbolic-ref", "$remote/HEAD", "$remote/$opt_o")
+	system(qw(git symbolic-ref), "$remote/HEAD", "$remote/$opt_o")
 		if ($opt_r && $opt_o ne 'HEAD');
-	system('git-update-ref', 'HEAD', "$orig_branch");
+	system(qw(git update-ref HEAD), "$orig_branch");
 	unless ($opt_i) {
-		system('git checkout -f');
+		system(qw(git checkout -f));
 		die "checkout failed: $?\n" if $?;
 	}
 }
-- 
1.6.6

^ permalink raw reply related

* [PATCH] ident.c: suppress fprintf compiler warning
From: Tarmigan Casebolt @ 2010-01-17  6:16 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git, Tarmigan Casebolt

Compiling today's pu gave
    ...
    CC ident.o
    CC levenshtein.o
ident.c: In function 'fmt_ident':
ident.c:206: warning: format not a string literal and no format arguments
    CC list-objects.o
    ...

This warning seems to have appeared first in 18e95f279ec6 (ident.c:
remove unused variables) which removed additional fprintf arguments.

Suppress this warning by using a literal "%s" to print the string
instead of passing the string directly to fprintf.

Signed-off-by: Tarmigan Casebolt <tarmigan+git@gmail.com>
---
 ident.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/ident.c b/ident.c
index d4f6145..239112c 100644
--- a/ident.c
+++ b/ident.c
@@ -203,7 +203,7 @@ const char *fmt_ident(const char *name, const char *email,
 
 		if ((warn_on_no_name || error_on_no_name) &&
 		    name == git_default_name && env_hint) {
-			fprintf(stderr, env_hint);
+			fprintf(stderr, "%s", env_hint);
 			env_hint = NULL; /* warn only once */
 		}
 		if (error_on_no_name)
-- 
1.6.6.425.g6b174

^ permalink raw reply related

* Get rid of refreshing cache after "git commit"?
From: Nguyen Thai Ngoc Duy @ 2010-01-17  8:16 UTC (permalink / raw)
  To: Git Mailing List

Hi,

The current "git commit" refreshes cache and writes out after a
commit. I dug back in history to see how it was introduced. It looks
like from the very first days of "git commit", which was
git-commit-script at that time, git-update-cache was called on
specified paths, until commit 22cff6a (git-commit: pass explicit path
to git-diff-files. - 2005-08-16) started to do "git-update-cache -q
--refresh" without paths and the tradition keeps going until today.

Nowadays almost (all?) porcelain commands silently refresh index
before doing anything relating to worktree, I wonder if this tradition
is still necessary. On (again) gentoo-x86 repository, taking out the
refresh part could cut down about 1 sec on total 3 secs from "git
commit -m foo".
-- 
Duy

^ permalink raw reply

* Re: Get rid of refreshing cache after "git commit"?
From: Junio C Hamano @ 2010-01-17  8:27 UTC (permalink / raw)
  To: Nguyen Thai Ngoc Duy; +Cc: Git Mailing List
In-Reply-To: <fcaeb9bf1001170016q5e285201r36f6030579cfa605@mail.gmail.com>

Nguyen Thai Ngoc Duy <pclouds@gmail.com> writes:

> Nowadays almost (all?) porcelain commands silently refresh index
> before doing anything relating to worktree, I wonder if this tradition
> is still necessary.

Inside "commit", various checks to see if/how worktree files are changed
are attempted by the libified diff-files/diff-index and they must be used
after you refresh the cache entries.

"git commit" (without paths) does not necessarily have to when you can
prove that the user never looks at .git/COMMIT_EDITMSG (e.g. "-F file" is
given without "-e"), but otherwise you need to refresh the index to show
the correct status in the message buffer.

"git commit paths..."  must refresh the named paths (not necessarily the
whole index), but again you would need the whole index to show the status
correctly.

^ permalink raw reply

* [PATCH] rm: only refresh entries that we may touch
From: Nguyễn Thái Ngọc Duy @ 2010-01-17  8:43 UTC (permalink / raw)
  To: git, Junio C Hamano; +Cc: Nguyễn Thái Ngọc Duy
In-Reply-To: <1263481341-28401-1-git-send-email-pclouds@gmail.com>

This gets rid of the whole tree cache refresh. Instead only path that
we touch will get refreshed. We may still lstat() more than needed,
but it'd be better playing safe.

This potentially reduces a large number of lstat() on big trees. Take
gentoo-x86 tree for example, which has roughly 80k files:

Unmodified Git:

$ time git rm --cached skel.ebuild
rm 'skel.ebuild'

real    0m1.441s
user    0m0.821s
sys     0m0.531s

Modified Git:

$ time ~/w/git/git rm --cached skel.ebuild
rm 'skel.ebuild'

real    0m0.941s
user    0m0.828s
sys     0m0.091s

Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
 In the previous attempt, refresh_cache_entry() returns a new cache_entry.
 It does not modify the_index, so tests failed.

 builtin-rm.c |    3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/builtin-rm.c b/builtin-rm.c
index 57975db..f3772c8 100644
--- a/builtin-rm.c
+++ b/builtin-rm.c
@@ -169,9 +169,10 @@ int cmd_rm(int argc, const char **argv, const char *prefix)
 
 	if (read_cache() < 0)
 		die("index file corrupt");
-	refresh_cache(REFRESH_QUIET);
 
 	pathspec = get_pathspec(prefix, argv);
+	refresh_index(&the_index, REFRESH_QUIET, pathspec, NULL, NULL);
+
 	seen = NULL;
 	for (i = 0; pathspec[i] ; i++)
 		/* nothing */;
-- 
1.6.6.181.g5ee6

^ permalink raw reply related

* Re: [PATCH v2 3/3] commit: show interesting ident information in summary
From: Junio C Hamano @ 2010-01-17  8:59 UTC (permalink / raw)
  To: Jeff King; +Cc: Adam Megacz, git
In-Reply-To: <20100113173951.GC16786@coredump.intra.peff.net>

Jeff King <peff@peff.net> writes:

> @@ -1046,9 +1058,12 @@ static void print_summary(const char *prefix, const unsigned char *sha1)
>  {
>  	struct rev_info rev;
>  	struct commit *commit;
> -	static const char *format = "format:%h] %s";
> +	struct strbuf format = STRBUF_INIT;
>  	unsigned char junk_sha1[20];
>  	const char *head = resolve_ref("HEAD", junk_sha1, 0, NULL);
> +	struct pretty_print_context pctx = {0};
> +	struct strbuf author_ident = STRBUF_INIT;
> +	struct strbuf committer_ident = STRBUF_INIT;
>  
>  	commit = lookup_commit(sha1);
>  	if (!commit)
> @@ -1056,6 +1071,23 @@ static void print_summary(const char *prefix, const unsigned char *sha1)
>  	if (!commit || parse_commit(commit))
>  		die("could not parse newly created commit");
>  
> +	strbuf_addstr(&format, "format:%h] %s");
> + ...
> +	if (strbuf_cmp(&author_ident, &committer_ident)) {
> +		strbuf_addstr(&format, "\n Author: ");
> +		strbuf_addbuf_percentquote(&format, &author_ident);
> +	}
> +	if (!user_ident_explicitly_given) {
> +		strbuf_addstr(&format, "\n Committer: ");
> +		strbuf_addbuf_percentquote(&format, &committer_ident);
> +		strbuf_addch(&format, '\n');
> +		strbuf_addstr(&format, implicit_ident_advice);
> +	}
> + ...
> -	get_commit_format(format, &rev);
> +	get_commit_format(format.buf, &rev);
> +	strbuf_release(&format);
>  	rev.always_show_header = 0;
>  	rev.diffopt.detect_rename = 1;
>  	rev.diffopt.rename_limit = 100;

This prepares the user format for log_tree_commit(); get_commit_format()
copies it away in its userformat, so it appears we are done with format
strbuf we built, and we release...

> @@ -1085,7 +1118,7 @@ static void print_summary(const char *prefix, const unsigned char *sha1)
>  		struct pretty_print_context ctx = {0};
>  		struct strbuf buf = STRBUF_INIT;
>  		ctx.date_mode = DATE_NORMAL;
> -		format_commit_message(commit, format + 7, &buf, &ctx);
> +		format_commit_message(commit, format.buf + 7, &buf, &ctx);
>  		printf("%s\n", buf.buf);

But sometimes log_tree_commit() doesn't show the header.  Most notably for
merges.  What string are we using for format_commit_message()?  Oops.

diff --git a/builtin-commit.c b/builtin-commit.c
index a73a532..7f61e87 100644
--- a/builtin-commit.c
+++ b/builtin-commit.c
@@ -1013,7 +1013,6 @@ static void print_summary(const char *prefix, const unsigned char *sha1)
 	rev.verbose_header = 1;
 	rev.show_root_diff = 1;
 	get_commit_format(format.buf, &rev);
-	strbuf_release(&format);
 	rev.always_show_header = 0;
 	rev.diffopt.detect_rename = 1;
 	rev.diffopt.rename_limit = 100;
@@ -1036,6 +1035,7 @@ static void print_summary(const char *prefix, const unsigned char *sha1)
 		printf("%s\n", buf.buf);
 		strbuf_release(&buf);
 	}
+	strbuf_release(&format);
 }
 
 static int git_commit_config(const char *k, const char *v, void *cb)

^ permalink raw reply related

* [PATCH 0/8] Rescuing repeated merge of Documentation/git-merge.txt
From: Junio C Hamano @ 2010-01-17  9:38 UTC (permalink / raw)
  To: git

Ever since I started queuing Thomas's documentation updates in 'pu',
rebuilding the branch involved manual re-integration for conflicts in
Documentation/git-merge.txt.  This is because the tracked contents in
the file has lines that exactly match the conflict marker patterns (of
course, they are examples of how conflicts are shown).

I am not blaming Thomas; the blame lies squarely on the inability of
'rerere' to deal with such a situation.  It often is enough to do:

	git diff pu@{4.hours} Documentation/git-merge.txt

to check that nothing else has changed since the last merge, and then

	git co pu@{4.hours} Documentation/git-merge.txt

to resurrect the previous result, but it still is irritating.

This series is to help me cope with this particular merge by allowing the
attribute mechanism.  By having this entry in my .git/info/attributes:

	Documentation/git-merge.txt	conflict-marker-size=32

"git merge" leaves conflict markers that are 32 chars long (instead of the
usual 7), "git rerere" that is run internally when "git merge" results in
conflicts sees only the real conflict markers as such without getting
confused by the example in the contents, and "git rerere" called to record
the resolution does the right thing.

Junio C Hamano (8):
  git_attr(): fix function signature
  xdl_merge(): introduce xmparam_t for merge specific parameters
  xdl_merge(): allow passing down marker_size in xmparam_t
  merge-tree: use ll_merge() not xdl_merge()
  rerere: use ll_merge() instead of using xdl_merge()
  conflict-marker-size: new attribute
  rerere: prepare for customizable conflict marker length
  rerere: honor conflict-marker-size attribute

 archive.c              |    4 +-
 attr.c                 |   11 +++++--
 attr.h                 |    2 +-
 builtin-check-attr.c   |    2 +-
 builtin-merge-file.c   |    4 +-
 builtin-pack-objects.c |    2 +-
 convert.c              |    6 ++--
 ll-merge.c             |   80 +++++++++++++++++++++++++++++++-----------------
 ll-merge.h             |    2 +
 merge-file.c           |   16 ++++-----
 merge-tree.c           |    4 +-
 rerere.c               |   57 +++++++++++++++++++++++++--------
 userdiff.c             |    2 +-
 ws.c                   |    2 +-
 xdiff/xdiff.h          |    9 +++++-
 xdiff/xmerge.c         |   26 ++++++++++-----
 16 files changed, 151 insertions(+), 78 deletions(-)

^ permalink raw reply

* [PATCH 1/8] git_attr(): fix function signature
From: Junio C Hamano @ 2010-01-17  9:38 UTC (permalink / raw)
  To: git
In-Reply-To: <1263721144-18605-1-git-send-email-gitster@pobox.com>

The function took (name, namelen) as its arguments, but all the public
callers wanted to pass a full string.

Demote the counted-string interface to an internal API status, and allow
public callers to just pass the string to the function.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 archive.c              |    4 ++--
 attr.c                 |   11 ++++++++---
 attr.h                 |    2 +-
 builtin-check-attr.c   |    2 +-
 builtin-pack-objects.c |    2 +-
 convert.c              |    6 +++---
 ll-merge.c             |    2 +-
 userdiff.c             |    2 +-
 ws.c                   |    2 +-
 9 files changed, 19 insertions(+), 14 deletions(-)

diff --git a/archive.c b/archive.c
index 55b2732..a9ebdc5 100644
--- a/archive.c
+++ b/archive.c
@@ -87,8 +87,8 @@ static void setup_archive_check(struct git_attr_check *check)
 	static struct git_attr *attr_export_subst;
 
 	if (!attr_export_ignore) {
-		attr_export_ignore = git_attr("export-ignore", 13);
-		attr_export_subst = git_attr("export-subst", 12);
+		attr_export_ignore = git_attr("export-ignore");
+		attr_export_subst = git_attr("export-subst");
 	}
 	check[0].attr = attr_export_ignore;
 	check[1].attr = attr_export_subst;
diff --git a/attr.c b/attr.c
index 55bdb7c..f5346ed 100644
--- a/attr.c
+++ b/attr.c
@@ -65,7 +65,7 @@ static int invalid_attr_name(const char *name, int namelen)
 	return 0;
 }
 
-struct git_attr *git_attr(const char *name, int len)
+static struct git_attr *git_attr_internal(const char *name, int len)
 {
 	unsigned hval = hash_name(name, len);
 	unsigned pos = hval % HASHSIZE;
@@ -95,6 +95,11 @@ struct git_attr *git_attr(const char *name, int len)
 	return a;
 }
 
+struct git_attr *git_attr(const char *name)
+{
+	return git_attr_internal(name, strlen(name));
+}
+
 /*
  * .gitattributes file is one line per record, each of which is
  *
@@ -162,7 +167,7 @@ static const char *parse_attr(const char *src, int lineno, const char *cp,
 		else {
 			e->setto = xmemdupz(equals + 1, ep - equals - 1);
 		}
-		e->attr = git_attr(cp, len);
+		e->attr = git_attr_internal(cp, len);
 	}
 	(*num_attr)++;
 	return ep + strspn(ep, blank);
@@ -221,7 +226,7 @@ static struct match_attr *parse_attr_line(const char *line, const char *src,
 			      sizeof(struct attr_state) * num_attr +
 			      (is_macro ? 0 : namelen + 1));
 		if (is_macro)
-			res->u.attr = git_attr(name, namelen);
+			res->u.attr = git_attr_internal(name, namelen);
 		else {
 			res->u.pattern = (char *)&(res->state[num_attr]);
 			memcpy(res->u.pattern, name, namelen);
diff --git a/attr.h b/attr.h
index 69b5767..450f49d 100644
--- a/attr.h
+++ b/attr.h
@@ -8,7 +8,7 @@ struct git_attr;
  * Given a string, return the gitattribute object that
  * corresponds to it.
  */
-struct git_attr *git_attr(const char *, int);
+struct git_attr *git_attr(const char *);
 
 /* Internal use */
 extern const char git_attr__true[];
diff --git a/builtin-check-attr.c b/builtin-check-attr.c
index 8bd0430..3016d29 100644
--- a/builtin-check-attr.c
+++ b/builtin-check-attr.c
@@ -106,7 +106,7 @@ int cmd_check_attr(int argc, const char **argv, const char *prefix)
 		const char *name;
 		struct git_attr *a;
 		name = argv[i];
-		a = git_attr(name, strlen(name));
+		a = git_attr(name);
 		if (!a)
 			return error("%s: not a valid attribute name", name);
 		check[i].attr = a;
diff --git a/builtin-pack-objects.c b/builtin-pack-objects.c
index 4429d53..9beff35 100644
--- a/builtin-pack-objects.c
+++ b/builtin-pack-objects.c
@@ -673,7 +673,7 @@ static void setup_delta_attr_check(struct git_attr_check *check)
 	static struct git_attr *attr_delta;
 
 	if (!attr_delta)
-		attr_delta = git_attr("delta", 5);
+		attr_delta = git_attr("delta");
 
 	check[0].attr = attr_delta;
 }
diff --git a/convert.c b/convert.c
index 491e714..852fd64 100644
--- a/convert.c
+++ b/convert.c
@@ -377,9 +377,9 @@ static void setup_convert_check(struct git_attr_check *check)
 	static struct git_attr *attr_filter;
 
 	if (!attr_crlf) {
-		attr_crlf = git_attr("crlf", 4);
-		attr_ident = git_attr("ident", 5);
-		attr_filter = git_attr("filter", 6);
+		attr_crlf = git_attr("crlf");
+		attr_ident = git_attr("ident");
+		attr_filter = git_attr("filter");
 		user_convert_tail = &user_convert;
 		git_config(read_convert_config, NULL);
 	}
diff --git a/ll-merge.c b/ll-merge.c
index 2d6b6d6..f4b0a07 100644
--- a/ll-merge.c
+++ b/ll-merge.c
@@ -344,7 +344,7 @@ static const char *git_path_check_merge(const char *path)
 	static struct git_attr_check attr_merge_check;
 
 	if (!attr_merge_check.attr)
-		attr_merge_check.attr = git_attr("merge", 5);
+		attr_merge_check.attr = git_attr("merge");
 
 	if (git_checkattr(path, 1, &attr_merge_check))
 		return NULL;
diff --git a/userdiff.c b/userdiff.c
index 57529ae..df99249 100644
--- a/userdiff.c
+++ b/userdiff.c
@@ -198,7 +198,7 @@ struct userdiff_driver *userdiff_find_by_path(const char *path)
 	struct git_attr_check check;
 
 	if (!attr)
-		attr = git_attr("diff", 4);
+		attr = git_attr("diff");
 	check.attr = attr;
 
 	if (!path)
diff --git a/ws.c b/ws.c
index 760b574..c089338 100644
--- a/ws.c
+++ b/ws.c
@@ -64,7 +64,7 @@ static void setup_whitespace_attr_check(struct git_attr_check *check)
 	static struct git_attr *attr_whitespace;
 
 	if (!attr_whitespace)
-		attr_whitespace = git_attr("whitespace", 10);
+		attr_whitespace = git_attr("whitespace");
 	check[0].attr = attr_whitespace;
 }
 
-- 
1.6.6.405.g80ed6.dirty

^ permalink raw reply related

* [PATCH 2/8] xdl_merge(): introduce xmparam_t for merge specific parameters
From: Junio C Hamano @ 2010-01-17  9:38 UTC (permalink / raw)
  To: git
In-Reply-To: <1263721144-18605-1-git-send-email-gitster@pobox.com>

So far we have only needed to be able to pass an option that is generic to
xdiff family of functions to this function.  Extend the interface so that
we can give it merge specific parameters.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 builtin-merge-file.c |    4 ++--
 ll-merge.c           |    6 +++---
 merge-file.c         |    6 +++---
 rerere.c             |    4 ++--
 xdiff/xdiff.h        |    6 +++++-
 xdiff/xmerge.c       |    3 ++-
 6 files changed, 17 insertions(+), 12 deletions(-)

diff --git a/builtin-merge-file.c b/builtin-merge-file.c
index afd2ea7..11c3524 100644
--- a/builtin-merge-file.c
+++ b/builtin-merge-file.c
@@ -25,7 +25,7 @@ int cmd_merge_file(int argc, const char **argv, const char *prefix)
 	const char *names[3] = { NULL, NULL, NULL };
 	mmfile_t mmfs[3];
 	mmbuffer_t result = {NULL, 0};
-	xpparam_t xpp = {XDF_NEED_MINIMAL};
+	xmparam_t xmp = {{XDF_NEED_MINIMAL}};
 	int ret = 0, i = 0, to_stdout = 0;
 	int merge_level = XDL_MERGE_ZEALOUS_ALNUM;
 	int merge_style = 0, quiet = 0;
@@ -68,7 +68,7 @@ int cmd_merge_file(int argc, const char **argv, const char *prefix)
 	}
 
 	ret = xdl_merge(mmfs + 1, mmfs + 0, names[0], mmfs + 2, names[2],
-			&xpp, merge_level | merge_style, &result);
+			&xmp, merge_level | merge_style, &result);
 
 	for (i = 0; i < 3; i++)
 		free(mmfs[i].ptr);
diff --git a/ll-merge.c b/ll-merge.c
index f4b0a07..be2bf43 100644
--- a/ll-merge.c
+++ b/ll-merge.c
@@ -61,7 +61,7 @@ static int ll_xdl_merge(const struct ll_merge_driver *drv_unused,
 			mmfile_t *src2, const char *name2,
 			int virtual_ancestor)
 {
-	xpparam_t xpp;
+	xmparam_t xmp;
 	int style = 0;
 
 	if (buffer_is_binary(orig->ptr, orig->size) ||
@@ -76,13 +76,13 @@ static int ll_xdl_merge(const struct ll_merge_driver *drv_unused,
 				       virtual_ancestor);
 	}
 
-	memset(&xpp, 0, sizeof(xpp));
+	memset(&xmp, 0, sizeof(xmp));
 	if (git_xmerge_style >= 0)
 		style = git_xmerge_style;
 	return xdl_merge(orig,
 			 src1, name1,
 			 src2, name2,
-			 &xpp, XDL_MERGE_ZEALOUS | style,
+			 &xmp, XDL_MERGE_ZEALOUS | style,
 			 result);
 }
 
diff --git a/merge-file.c b/merge-file.c
index 3120a95..5c00c7e 100644
--- a/merge-file.c
+++ b/merge-file.c
@@ -27,12 +27,12 @@ static void free_mmfile(mmfile_t *f)
 static void *three_way_filemerge(mmfile_t *base, mmfile_t *our, mmfile_t *their, unsigned long *size)
 {
 	mmbuffer_t res;
-	xpparam_t xpp;
+	xmparam_t xmp;
 	int merge_status;
 
-	memset(&xpp, 0, sizeof(xpp));
+	memset(&xmp, 0, sizeof(xmp));
 	merge_status = xdl_merge(base, our, ".our", their, ".their",
-		&xpp, XDL_MERGE_ZEALOUS, &res);
+		&xmp, XDL_MERGE_ZEALOUS, &res);
 
 	if (merge_status < 0)
 		return NULL;
diff --git a/rerere.c b/rerere.c
index d92990a..adb0694 100644
--- a/rerere.c
+++ b/rerere.c
@@ -332,7 +332,7 @@ static int merge(const char *name, const char *path)
 	int ret;
 	mmfile_t cur, base, other;
 	mmbuffer_t result = {NULL, 0};
-	xpparam_t xpp = {XDF_NEED_MINIMAL};
+	xmparam_t xmp = {{XDF_NEED_MINIMAL}};
 
 	if (handle_file(path, NULL, rerere_path(name, "thisimage")) < 0)
 		return 1;
@@ -342,7 +342,7 @@ static int merge(const char *name, const char *path)
 			read_mmfile(&other, rerere_path(name, "postimage")))
 		return 1;
 	ret = xdl_merge(&base, &cur, "", &other, "",
-			&xpp, XDL_MERGE_ZEALOUS, &result);
+			&xmp, XDL_MERGE_ZEALOUS, &result);
 	if (!ret) {
 		FILE *f = fopen(path, "w");
 		if (!f)
diff --git a/xdiff/xdiff.h b/xdiff/xdiff.h
index 4da052a..b265909 100644
--- a/xdiff/xdiff.h
+++ b/xdiff/xdiff.h
@@ -108,9 +108,13 @@ long xdl_mmfile_size(mmfile_t *mmf);
 int xdl_diff(mmfile_t *mf1, mmfile_t *mf2, xpparam_t const *xpp,
 	     xdemitconf_t const *xecfg, xdemitcb_t *ecb);
 
+typedef struct s_xmparam {
+	xpparam_t xpp;
+} xmparam_t;
+
 int xdl_merge(mmfile_t *orig, mmfile_t *mf1, const char *name1,
 		mmfile_t *mf2, const char *name2,
-		xpparam_t const *xpp, int level, mmbuffer_t *result);
+		xmparam_t const *xmp, int level, mmbuffer_t *result);
 
 #ifdef __cplusplus
 }
diff --git a/xdiff/xmerge.c b/xdiff/xmerge.c
index 1cb65a9..5c37b4e 100644
--- a/xdiff/xmerge.c
+++ b/xdiff/xmerge.c
@@ -538,10 +538,11 @@ static int xdl_do_merge(xdfenv_t *xe1, xdchange_t *xscr1, const char *name1,
 
 int xdl_merge(mmfile_t *orig, mmfile_t *mf1, const char *name1,
 		mmfile_t *mf2, const char *name2,
-		xpparam_t const *xpp, int flags, mmbuffer_t *result) {
+		xmparam_t const *xmp, int flags, mmbuffer_t *result) {
 	xdchange_t *xscr1, *xscr2;
 	xdfenv_t xe1, xe2;
 	int status;
+	xpparam_t const *xpp = &xmp->xpp;
 
 	result->ptr = NULL;
 	result->size = 0;
-- 
1.6.6.405.g80ed6.dirty

^ permalink raw reply related

* [PATCH 3/8] xdl_merge(): allow passing down marker_size in xmparam_t
From: Junio C Hamano @ 2010-01-17  9:38 UTC (permalink / raw)
  To: git
In-Reply-To: <1263721144-18605-1-git-send-email-gitster@pobox.com>

This allows the callers of xdl_merge() to pass marker_size (defaults to 7)
in xmparam_t argument, to use conflict markers of non-default length.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 xdiff/xdiff.h  |    3 +++
 xdiff/xmerge.c |   23 +++++++++++++++--------
 2 files changed, 18 insertions(+), 8 deletions(-)

diff --git a/xdiff/xdiff.h b/xdiff/xdiff.h
index b265909..22f3913 100644
--- a/xdiff/xdiff.h
+++ b/xdiff/xdiff.h
@@ -110,8 +110,11 @@ int xdl_diff(mmfile_t *mf1, mmfile_t *mf2, xpparam_t const *xpp,
 
 typedef struct s_xmparam {
 	xpparam_t xpp;
+	int marker_size;
 } xmparam_t;
 
+#define DEFAULT_CONFLICT_MARKER_SIZE 7
+
 int xdl_merge(mmfile_t *orig, mmfile_t *mf1, const char *name1,
 		mmfile_t *mf2, const char *name2,
 		xmparam_t const *xmp, int level, mmbuffer_t *result);
diff --git a/xdiff/xmerge.c b/xdiff/xmerge.c
index 5c37b4e..68c815f 100644
--- a/xdiff/xmerge.c
+++ b/xdiff/xmerge.c
@@ -145,13 +145,15 @@ static int xdl_orig_copy(xdfenv_t *xe, int i, int count, int add_nl, char *dest)
 static int fill_conflict_hunk(xdfenv_t *xe1, const char *name1,
 			      xdfenv_t *xe2, const char *name2,
 			      int size, int i, int style,
-			      xdmerge_t *m, char *dest)
+			      xdmerge_t *m, char *dest, int marker_size)
 {
-	const int marker_size = 7;
 	int marker1_size = (name1 ? strlen(name1) + 1 : 0);
 	int marker2_size = (name2 ? strlen(name2) + 1 : 0);
 	int j;
 
+	if (marker_size <= 0)
+		marker_size = DEFAULT_CONFLICT_MARKER_SIZE;
+
 	/* Before conflicting part */
 	size += xdl_recs_copy(xe1, i, m->i1 - i, 0,
 			      dest ? dest + size : NULL);
@@ -214,14 +216,16 @@ static int fill_conflict_hunk(xdfenv_t *xe1, const char *name1,
 
 static int xdl_fill_merge_buffer(xdfenv_t *xe1, const char *name1,
 				 xdfenv_t *xe2, const char *name2,
-				 xdmerge_t *m, char *dest, int style)
+				 xdmerge_t *m, char *dest, int style,
+				 int marker_size)
 {
 	int size, i;
 
 	for (size = i = 0; m; m = m->next) {
 		if (m->mode == 0)
 			size = fill_conflict_hunk(xe1, name1, xe2, name2,
-						  size, i, style, m, dest);
+						  size, i, style, m, dest,
+						  marker_size);
 		else if (m->mode == 1)
 			size += xdl_recs_copy(xe1, i, m->i1 + m->chg1 - i, 0,
 					      dest ? dest + size : NULL);
@@ -386,8 +390,9 @@ static int xdl_simplify_non_conflicts(xdfenv_t *xe1, xdmerge_t *m,
  */
 static int xdl_do_merge(xdfenv_t *xe1, xdchange_t *xscr1, const char *name1,
 		xdfenv_t *xe2, xdchange_t *xscr2, const char *name2,
-		int flags, xpparam_t const *xpp, mmbuffer_t *result) {
+		int flags, xmparam_t const *xmp, mmbuffer_t *result) {
 	xdmerge_t *changes, *c;
+	xpparam_t const *xpp = &xmp->xpp;
 	int i0, i1, i2, chg0, chg1, chg2;
 	int level = flags & XDL_MERGE_LEVEL_MASK;
 	int style = flags & XDL_MERGE_STYLE_MASK;
@@ -522,8 +527,10 @@ static int xdl_do_merge(xdfenv_t *xe1, xdchange_t *xscr1, const char *name1,
 	}
 	/* output */
 	if (result) {
+		int marker_size = xmp->marker_size;
 		int size = xdl_fill_merge_buffer(xe1, name1, xe2, name2,
-			changes, NULL, style);
+						 changes, NULL, style,
+						 marker_size);
 		result->ptr = xdl_malloc(size);
 		if (!result->ptr) {
 			xdl_cleanup_merge(changes);
@@ -531,7 +538,7 @@ static int xdl_do_merge(xdfenv_t *xe1, xdchange_t *xscr1, const char *name1,
 		}
 		result->size = size;
 		xdl_fill_merge_buffer(xe1, name1, xe2, name2, changes,
-				      result->ptr, style);
+				      result->ptr, style, marker_size);
 	}
 	return xdl_cleanup_merge(changes);
 }
@@ -575,7 +582,7 @@ int xdl_merge(mmfile_t *orig, mmfile_t *mf1, const char *name1,
 	} else {
 		status = xdl_do_merge(&xe1, xscr1, name1,
 				      &xe2, xscr2, name2,
-				      flags, xpp, result);
+				      flags, xmp, result);
 	}
 	xdl_free_script(xscr1);
 	xdl_free_script(xscr2);
-- 
1.6.6.405.g80ed6.dirty

^ permalink raw reply related

* [PATCH 4/8] merge-tree: use ll_merge() not xdl_merge()
From: Junio C Hamano @ 2010-01-17  9:39 UTC (permalink / raw)
  To: git; +Cc: Linus Torvalds
In-Reply-To: <1263721144-18605-1-git-send-email-gitster@pobox.com>

ll_merge() interface was designed to merge contents under git control
while taking per-path attributes into account.  Update the three-way
merge implementation used by merge-tree to use it.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 merge-file.c |   16 +++++++---------
 merge-tree.c |    4 ++--
 2 files changed, 9 insertions(+), 11 deletions(-)

diff --git a/merge-file.c b/merge-file.c
index 5c00c7e..fd34d76 100644
--- a/merge-file.c
+++ b/merge-file.c
@@ -1,6 +1,7 @@
 #include "cache.h"
 #include "run-command.h"
 #include "xdiff-interface.h"
+#include "ll-merge.h"
 #include "blob.h"
 
 static int fill_mmfile_blob(mmfile_t *f, struct blob *obj)
@@ -24,16 +25,13 @@ static void free_mmfile(mmfile_t *f)
 	free(f->ptr);
 }
 
-static void *three_way_filemerge(mmfile_t *base, mmfile_t *our, mmfile_t *their, unsigned long *size)
+static void *three_way_filemerge(const char *path, mmfile_t *base, mmfile_t *our, mmfile_t *their, unsigned long *size)
 {
-	mmbuffer_t res;
-	xmparam_t xmp;
 	int merge_status;
+	mmbuffer_t res;
 
-	memset(&xmp, 0, sizeof(xmp));
-	merge_status = xdl_merge(base, our, ".our", their, ".their",
-		&xmp, XDL_MERGE_ZEALOUS, &res);
-
+	merge_status = ll_merge(&res, path, base,
+				our, ".our", their, ".their", 0);
 	if (merge_status < 0)
 		return NULL;
 
@@ -75,7 +73,7 @@ static int generate_common_file(mmfile_t *res, mmfile_t *f1, mmfile_t *f2)
 	return xdi_diff(f1, f2, &xpp, &xecfg, &ecb);
 }
 
-void *merge_file(struct blob *base, struct blob *our, struct blob *their, unsigned long *size)
+void *merge_file(const char *path, struct blob *base, struct blob *our, struct blob *their, unsigned long *size)
 {
 	void *res = NULL;
 	mmfile_t f1, f2, common;
@@ -108,7 +106,7 @@ void *merge_file(struct blob *base, struct blob *our, struct blob *their, unsign
 		if (generate_common_file(&common, &f1, &f2) < 0)
 			goto out_free_f2_f1;
 	}
-	res = three_way_filemerge(&common, &f1, &f2, size);
+	res = three_way_filemerge(path, &common, &f1, &f2, size);
 	free_mmfile(&common);
 out_free_f2_f1:
 	free_mmfile(&f2);
diff --git a/merge-tree.c b/merge-tree.c
index f01e7c8..37b94d9 100644
--- a/merge-tree.c
+++ b/merge-tree.c
@@ -54,7 +54,7 @@ static const char *explanation(struct merge_list *entry)
 	return "removed in remote";
 }
 
-extern void *merge_file(struct blob *, struct blob *, struct blob *, unsigned long *);
+extern void *merge_file(const char *, struct blob *, struct blob *, struct blob *, unsigned long *);
 
 static void *result(struct merge_list *entry, unsigned long *size)
 {
@@ -76,7 +76,7 @@ static void *result(struct merge_list *entry, unsigned long *size)
 	their = NULL;
 	if (entry)
 		their = entry->blob;
-	return merge_file(base, our, their, size);
+	return merge_file(entry->path, base, our, their, size);
 }
 
 static void *origin(struct merge_list *entry, unsigned long *size)
-- 
1.6.6.405.g80ed6.dirty

^ permalink raw reply related

* [PATCH 7/8] rerere: prepare for customizable conflict marker length
From: Junio C Hamano @ 2010-01-17  9:39 UTC (permalink / raw)
  To: git
In-Reply-To: <1263721144-18605-1-git-send-email-gitster@pobox.com>

This still uses the hardcoded conflict marker length of 7 but otherwise
prepares the codepath to deal with customized marker length.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 rerere.c |   51 +++++++++++++++++++++++++++++++++++++++++----------
 1 files changed, 41 insertions(+), 10 deletions(-)

diff --git a/rerere.c b/rerere.c
index 5b8ebcb..d4d1507 100644
--- a/rerere.c
+++ b/rerere.c
@@ -98,6 +98,25 @@ static void rerere_io_putstr(const char *str, struct rerere_io *io)
 		ferr_puts(str, io->output, &io->wrerror);
 }
 
+static void rerere_io_putconflict(int ch, int size, struct rerere_io *io)
+{
+	char buf[64];
+
+	while (size) {
+		if (size + 2 < sizeof(buf)) {
+			memset(buf, ch, size);
+			buf[size] = '\n';
+			buf[size + 1] = '\0';
+			size = 0;
+		} else {
+			memset(buf, ch, sizeof(buf) - 1);
+			buf[sizeof(buf) - 1] = '\0';
+			size -= sizeof(buf) - 1;
+		}
+		rerere_io_putstr(buf, io);
+	}
+}
+
 static void rerere_io_putmem(const char *mem, size_t sz, struct rerere_io *io)
 {
 	if (io->output)
@@ -115,7 +134,17 @@ static int rerere_file_getline(struct strbuf *sb, struct rerere_io *io_)
 	return strbuf_getwholeline(sb, io->input, '\n');
 }
 
-static int handle_path(unsigned char *sha1, struct rerere_io *io)
+static int is_cmarker(char *buf, int marker_char, int marker_size, int want_sp)
+{
+	while (marker_size--)
+		if (*buf++ != marker_char)
+			return 0;
+	if (want_sp && *buf != ' ')
+		return 0;
+	return isspace(*buf);
+}
+
+static int handle_path(unsigned char *sha1, struct rerere_io *io, int marker_size)
 {
 	git_SHA_CTX ctx;
 	int hunk_no = 0;
@@ -129,30 +158,30 @@ static int handle_path(unsigned char *sha1, struct rerere_io *io)
 		git_SHA1_Init(&ctx);
 
 	while (!io->getline(&buf, io)) {
-		if (!prefixcmp(buf.buf, "<<<<<<< ")) {
+		if (is_cmarker(buf.buf, '<', marker_size, 1)) {
 			if (hunk != RR_CONTEXT)
 				goto bad;
 			hunk = RR_SIDE_1;
-		} else if (!prefixcmp(buf.buf, "|||||||") && isspace(buf.buf[7])) {
+		} else if (is_cmarker(buf.buf, '|', marker_size, 0)) {
 			if (hunk != RR_SIDE_1)
 				goto bad;
 			hunk = RR_ORIGINAL;
-		} else if (!prefixcmp(buf.buf, "=======") && isspace(buf.buf[7])) {
+		} else if (is_cmarker(buf.buf, '=', marker_size, 0)) {
 			if (hunk != RR_SIDE_1 && hunk != RR_ORIGINAL)
 				goto bad;
 			hunk = RR_SIDE_2;
-		} else if (!prefixcmp(buf.buf, ">>>>>>> ")) {
+		} else if (is_cmarker(buf.buf, '>', marker_size, 1)) {
 			if (hunk != RR_SIDE_2)
 				goto bad;
 			if (strbuf_cmp(&one, &two) > 0)
 				strbuf_swap(&one, &two);
 			hunk_no++;
 			hunk = RR_CONTEXT;
-			rerere_io_putstr("<<<<<<<\n", io);
+			rerere_io_putconflict('<', marker_size, io);
 			rerere_io_putmem(one.buf, one.len, io);
-			rerere_io_putstr("=======\n", io);
+			rerere_io_putconflict('=', marker_size, io);
 			rerere_io_putmem(two.buf, two.len, io);
-			rerere_io_putstr(">>>>>>>\n", io);
+			rerere_io_putconflict('>', marker_size, io);
 			if (sha1) {
 				git_SHA1_Update(&ctx, one.buf ? one.buf : "",
 					    one.len + 1);
@@ -189,6 +218,7 @@ static int handle_file(const char *path, unsigned char *sha1, const char *output
 {
 	int hunk_no = 0;
 	struct rerere_io_file io;
+	int marker_size = 7;
 
 	memset(&io, 0, sizeof(io));
 	io.io.getline = rerere_file_getline;
@@ -205,7 +235,7 @@ static int handle_file(const char *path, unsigned char *sha1, const char *output
 		}
 	}
 
-	hunk_no = handle_path(sha1, (struct rerere_io *)&io);
+	hunk_no = handle_path(sha1, (struct rerere_io *)&io, marker_size);
 
 	fclose(io.input);
 	if (io.io.wrerror)
@@ -255,6 +285,7 @@ static int handle_cache(const char *path, unsigned char *sha1, const char *outpu
 	struct cache_entry *ce;
 	int pos, len, i, hunk_no;
 	struct rerere_io_mem io;
+	int marker_size = 7;
 
 	/*
 	 * Reproduce the conflicted merge in-core
@@ -299,7 +330,7 @@ static int handle_cache(const char *path, unsigned char *sha1, const char *outpu
 	strbuf_init(&io.input, 0);
 	strbuf_attach(&io.input, result.ptr, result.size, result.size);
 
-	hunk_no = handle_path(sha1, (struct rerere_io *)&io);
+	hunk_no = handle_path(sha1, (struct rerere_io *)&io, marker_size);
 	strbuf_release(&io.input);
 	if (io.io.output)
 		fclose(io.io.output);
-- 
1.6.6.405.g80ed6.dirty

^ permalink raw reply related

* [PATCH 6/8] conflict-marker-size: new attribute
From: Junio C Hamano @ 2010-01-17  9:39 UTC (permalink / raw)
  To: git
In-Reply-To: <1263721144-18605-1-git-send-email-gitster@pobox.com>

This can be specified to set the length of the conflict marker (usually 7)
to a non-default value per path.  Only the callers of ll_merge() that are
aware of the per-path attributes are modified.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 ll-merge.c |   59 ++++++++++++++++++++++++++++++++++-------------------------
 1 files changed, 34 insertions(+), 25 deletions(-)

diff --git a/ll-merge.c b/ll-merge.c
index be2bf43..d682071 100644
--- a/ll-merge.c
+++ b/ll-merge.c
@@ -18,7 +18,8 @@ typedef int (*ll_merge_fn)(const struct ll_merge_driver *,
 			   mmfile_t *orig,
 			   mmfile_t *src1, const char *name1,
 			   mmfile_t *src2, const char *name2,
-			   int virtual_ancestor);
+			   int virtual_ancestor,
+			   int marker_size);
 
 struct ll_merge_driver {
 	const char *name;
@@ -38,7 +39,7 @@ static int ll_binary_merge(const struct ll_merge_driver *drv_unused,
 			   mmfile_t *orig,
 			   mmfile_t *src1, const char *name1,
 			   mmfile_t *src2, const char *name2,
-			   int virtual_ancestor)
+			   int virtual_ancestor, int marker_size)
 {
 	/*
 	 * The tentative merge result is "ours" for the final round,
@@ -59,7 +60,7 @@ static int ll_xdl_merge(const struct ll_merge_driver *drv_unused,
 			mmfile_t *orig,
 			mmfile_t *src1, const char *name1,
 			mmfile_t *src2, const char *name2,
-			int virtual_ancestor)
+			int virtual_ancestor, int marker_size)
 {
 	xmparam_t xmp;
 	int style = 0;
@@ -73,12 +74,14 @@ static int ll_xdl_merge(const struct ll_merge_driver *drv_unused,
 				       path,
 				       orig, src1, name1,
 				       src2, name2,
-				       virtual_ancestor);
+				       virtual_ancestor, marker_size);
 	}
 
 	memset(&xmp, 0, sizeof(xmp));
 	if (git_xmerge_style >= 0)
 		style = git_xmerge_style;
+	if (marker_size > 0)
+		xmp.marker_size = marker_size;
 	return xdl_merge(orig,
 			 src1, name1,
 			 src2, name2,
@@ -92,11 +95,10 @@ static int ll_union_merge(const struct ll_merge_driver *drv_unused,
 			  mmfile_t *orig,
 			  mmfile_t *src1, const char *name1,
 			  mmfile_t *src2, const char *name2,
-			  int virtual_ancestor)
+			  int virtual_ancestor, int marker_size)
 {
 	char *src, *dst;
 	long size;
-	const int marker_size = 7;
 	int status, saved_style;
 
 	/* We have to force the RCS "merge" style */
@@ -104,7 +106,7 @@ static int ll_union_merge(const struct ll_merge_driver *drv_unused,
 	git_xmerge_style = 0;
 	status = ll_xdl_merge(drv_unused, result, path_unused,
 			      orig, src1, NULL, src2, NULL,
-			      virtual_ancestor);
+			      virtual_ancestor, marker_size);
 	git_xmerge_style = saved_style;
 	if (status <= 0)
 		return status;
@@ -165,14 +167,15 @@ static int ll_ext_merge(const struct ll_merge_driver *fn,
 			mmfile_t *orig,
 			mmfile_t *src1, const char *name1,
 			mmfile_t *src2, const char *name2,
-			int virtual_ancestor)
+			int virtual_ancestor, int marker_size)
 {
-	char temp[3][50];
+	char temp[4][50];
 	struct strbuf cmd = STRBUF_INIT;
 	struct strbuf_expand_dict_entry dict[] = {
 		{ "O", temp[0] },
 		{ "A", temp[1] },
 		{ "B", temp[2] },
+		{ "L", temp[3] },
 		{ NULL }
 	};
 	const char *args[] = { "sh", "-c", NULL, NULL };
@@ -187,6 +190,7 @@ static int ll_ext_merge(const struct ll_merge_driver *fn,
 	create_temp(orig, temp[0]);
 	create_temp(src1, temp[1]);
 	create_temp(src2, temp[2]);
+	sprintf(temp[3], "%d", marker_size);
 
 	strbuf_expand(&cmd, fn->cmdline, strbuf_expand_dict_cb, &dict);
 
@@ -279,6 +283,7 @@ static int read_merge_config(const char *var, const char *value, void *cb)
 		 *    %O - temporary file name for the merge base.
 		 *    %A - temporary file name for our version.
 		 *    %B - temporary file name for the other branches' version.
+		 *    %L - conflict marker length
 		 *
 		 * The external merge driver should write the results in the
 		 * file named by %A, and signal that it has done with zero exit
@@ -339,16 +344,13 @@ static const struct ll_merge_driver *find_ll_merge_driver(const char *merge_attr
 	return &ll_merge_drv[LL_TEXT_MERGE];
 }
 
-static const char *git_path_check_merge(const char *path)
+static int git_path_check_merge(const char *path, struct git_attr_check check[2])
 {
-	static struct git_attr_check attr_merge_check;
-
-	if (!attr_merge_check.attr)
-		attr_merge_check.attr = git_attr("merge");
-
-	if (git_checkattr(path, 1, &attr_merge_check))
-		return NULL;
-	return attr_merge_check.value;
+	if (!check[0].attr) {
+		check[0].attr = git_attr("merge");
+		check[1].attr = git_attr("conflict-marker-size");
+	}
+	return git_checkattr(path, 2, check);
 }
 
 int ll_merge(mmbuffer_t *result_buf,
@@ -358,16 +360,23 @@ int ll_merge(mmbuffer_t *result_buf,
 	     mmfile_t *theirs, const char *their_label,
 	     int virtual_ancestor)
 {
-	const char *ll_driver_name;
+	static struct git_attr_check check[2];
+	const char *ll_driver_name = NULL;
+	int marker_size = DEFAULT_CONFLICT_MARKER_SIZE;
 	const struct ll_merge_driver *driver;
 
-	ll_driver_name = git_path_check_merge(path);
+	if (!git_path_check_merge(path, check)) {
+		ll_driver_name = check[0].value;
+		if (check[1].value) {
+			marker_size = atoi(check[1].value);
+			if (marker_size <= 0)
+				marker_size = DEFAULT_CONFLICT_MARKER_SIZE;
+		}
+	}
 	driver = find_ll_merge_driver(ll_driver_name);
-
 	if (virtual_ancestor && driver->recursive)
 		driver = find_ll_merge_driver(driver->recursive);
-	return driver->fn(driver, result_buf, path,
-			  ancestor,
-			  ours, our_label,
-			  theirs, their_label, virtual_ancestor);
+	return driver->fn(driver, result_buf, path, ancestor,
+			  ours, our_label, theirs, their_label,
+			  virtual_ancestor, marker_size);
 }
-- 
1.6.6.405.g80ed6.dirty

^ permalink raw reply related

* [PATCH 8/8] rerere: honor conflict-marker-size attribute
From: Junio C Hamano @ 2010-01-17  9:39 UTC (permalink / raw)
  To: git
In-Reply-To: <1263721144-18605-1-git-send-email-gitster@pobox.com>

Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 ll-merge.c |   15 +++++++++++++++
 ll-merge.h |    2 ++
 rerere.c   |    5 +++--
 3 files changed, 20 insertions(+), 2 deletions(-)

diff --git a/ll-merge.c b/ll-merge.c
index d682071..0dcaae0 100644
--- a/ll-merge.c
+++ b/ll-merge.c
@@ -380,3 +380,18 @@ int ll_merge(mmbuffer_t *result_buf,
 			  ours, our_label, theirs, their_label,
 			  virtual_ancestor, marker_size);
 }
+
+int ll_merge_marker_size(const char *path)
+{
+	static struct git_attr_check check;
+	int marker_size = DEFAULT_CONFLICT_MARKER_SIZE;
+
+	if (!check.attr)
+		check.attr = git_attr("conflict-marker-size");
+	if (!git_checkattr(path, 1, &check) && check.value) {
+		marker_size = atoi(check.value);
+		if (marker_size <= 0)
+			marker_size = DEFAULT_CONFLICT_MARKER_SIZE;
+	}
+	return marker_size;
+}
diff --git a/ll-merge.h b/ll-merge.h
index 5388422..ff5d84a 100644
--- a/ll-merge.h
+++ b/ll-merge.h
@@ -12,4 +12,6 @@ int ll_merge(mmbuffer_t *result_buf,
 	     mmfile_t *theirs, const char *their_label,
 	     int virtual_ancestor);
 
+int ll_merge_marker_size(const char *path);
+
 #endif
diff --git a/rerere.c b/rerere.c
index d4d1507..2a2bd23 100644
--- a/rerere.c
+++ b/rerere.c
@@ -5,6 +5,7 @@
 #include "dir.h"
 #include "resolve-undo.h"
 #include "ll-merge.h"
+#include "attr.h"
 
 /* if rerere_enabled == -1, fall back to detection of .git/rr-cache */
 static int rerere_enabled = -1;
@@ -218,7 +219,7 @@ static int handle_file(const char *path, unsigned char *sha1, const char *output
 {
 	int hunk_no = 0;
 	struct rerere_io_file io;
-	int marker_size = 7;
+	int marker_size = ll_merge_marker_size(path);
 
 	memset(&io, 0, sizeof(io));
 	io.io.getline = rerere_file_getline;
@@ -285,7 +286,7 @@ static int handle_cache(const char *path, unsigned char *sha1, const char *outpu
 	struct cache_entry *ce;
 	int pos, len, i, hunk_no;
 	struct rerere_io_mem io;
-	int marker_size = 7;
+	int marker_size = ll_merge_marker_size(path);
 
 	/*
 	 * Reproduce the conflicted merge in-core
-- 
1.6.6.405.g80ed6.dirty

^ permalink raw reply related

* [PATCH 5/8] rerere: use ll_merge() instead of using xdl_merge()
From: Junio C Hamano @ 2010-01-17  9:39 UTC (permalink / raw)
  To: git; +Cc: Johannes Sixt
In-Reply-To: <1263721144-18605-1-git-send-email-gitster@pobox.com>

This allows us to pay attention to the attribute settings and custom
merge driver the user sets up.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 rerere.c |    5 +----
 1 files changed, 1 insertions(+), 4 deletions(-)

diff --git a/rerere.c b/rerere.c
index adb0694..5b8ebcb 100644
--- a/rerere.c
+++ b/rerere.c
@@ -1,7 +1,6 @@
 #include "cache.h"
 #include "string-list.h"
 #include "rerere.h"
-#include "xdiff/xdiff.h"
 #include "xdiff-interface.h"
 #include "dir.h"
 #include "resolve-undo.h"
@@ -332,7 +331,6 @@ static int merge(const char *name, const char *path)
 	int ret;
 	mmfile_t cur, base, other;
 	mmbuffer_t result = {NULL, 0};
-	xmparam_t xmp = {{XDF_NEED_MINIMAL}};
 
 	if (handle_file(path, NULL, rerere_path(name, "thisimage")) < 0)
 		return 1;
@@ -341,8 +339,7 @@ static int merge(const char *name, const char *path)
 			read_mmfile(&base, rerere_path(name, "preimage")) ||
 			read_mmfile(&other, rerere_path(name, "postimage")))
 		return 1;
-	ret = xdl_merge(&base, &cur, "", &other, "",
-			&xmp, XDL_MERGE_ZEALOUS, &result);
+	ret = ll_merge(&result, path, &base, &cur, "", &other, "", 0);
 	if (!ret) {
 		FILE *f = fopen(path, "w");
 		if (!f)
-- 
1.6.6.405.g80ed6.dirty

^ permalink raw reply related

* ambiguous argument '...': unknown revision or path not in the working tree
From: Sven Joachim @ 2010-01-17  9:46 UTC (permalink / raw)
  To: git

I've got a strange error message in 'git push':

,----
| % git push
| Counting objects: 47, done.
| Delta compression using up to 2 threads.
| Compressing objects: 100% (24/24), done.
| Writing objects: 100% (24/24), 4.37 KiB, done.
| Total 24 (delta 22), reused 0 (delta 0)
| fatal: ambiguous argument '3bbc6def8a06e4411bee130b811ff9507e90503d:debian/changelog': unknown revision or path not in the working tree.
| Use '--' to separate paths from revisions
| To git+ssh://git.debian.org/git/collab-maint/ncurses.git
|    2fec7db..3bbc6de  HEAD -> upstream
`----

Indeed debian/changelog is not in the working tree, it is not in the
current branch (upstream) at all, although it exists in the master
branch.  Default is to push the current branch:

,----
| % git config --get push.default 
| current
| % git --version
| git version 1.6.6
`----

Despite the error message, the push was apparently successful; the
repository I push to can be found at
http://git.debian.org/?p=collab-maint/ncurses.git.

Sven

^ permalink raw reply

* Re: [PATCH 0/8] Rescuing repeated merge of Documentation/git-merge.txt
From: Junio C Hamano @ 2010-01-17 10:07 UTC (permalink / raw)
  To: git
In-Reply-To: <1263721144-18605-1-git-send-email-gitster@pobox.com>

7th one of the series has a minor nit; I fixed it up before pushing it out
to 'pu'.

^ permalink raw reply

* Re: [PATCH v2 3/3] commit: show interesting ident information in summary
From: Matthieu Moy @ 2010-01-17 11:31 UTC (permalink / raw)
  To: Wincent Colaiuta; +Cc: Jeff King, Junio C Hamano, Adam Megacz, git
In-Reply-To: <1DDB570B-350A-40A0-B6E4-ADBDF4BE6BD2@wincent.com>

Wincent Colaiuta <win@wincent.com> writes:

> I'll never see this message myself, but I think you could (and perhaps
> should) replace almost all of that with:
>
>   Your name and email address were configured automatically.
>   See "git config help" for information on setting them explicitly
>   or "git commit help" if you wish to amend this commit.

I don't think this is a good idea. The two main cases when this
information will be shown is:

* Newbies, who didn't read the doc, or read it too fast. They'll
  happily ignore your short message.

  For example, I just started a project with 200 students. The doc we
  give them _starts_ with setting user/email in ~/.gitconfig, right
  before we give them the URL of the repository they'll work on. Out
  of that, 22 email adresses were mis-configured. Don't underestimate
  the ability of newbies not to read doc, even when told to do so.

  If the message is long, it'll be disturbing, and they may end up
  reading it.

* Non-newbies, using a machine for the first time. These users will
  see the message once, so it's not really disturbing, and at least I
  would appreciate the message to be flashy, to make sure I don't miss
  it.

-- 
Matthieu Moy
http://www-verimag.imag.fr/~moy/

^ permalink raw reply

* Re: git rm --cached and pull semantics
From: Matthieu Moy @ 2010-01-17 11:42 UTC (permalink / raw)
  To: list; +Cc: git
In-Reply-To: <4B51EE39.3010401@phuk.ath.cx>

list@phuk.ath.cx writes:

> Hello everyone,
>
> I'm trying to manage and distribute a subset of /etc with git.
> Therefore, I have * in .gitignore and use git add -f to add files. Now
> sometimes I want to un-track a file that has been in previous commits,
> but naturally I don't want the file deleted. I just want git to ignore
> it again. As I read it, the way to do that is "git rm --cached $file".
> On the local working tree, that works as expected, but when some remote
> machine pulls a subsequent commit, it deletes the file from its working
> tree. But I just want git to ignore the file again, just as it does in
> the origin repo. How can I do that?

I'd say there's no way, and there will hardly ever be any :-(.

Git is purely snapshot-oriented, which means that when you do a "git
rm --cached", the next commit doesn't say "this file has been
removed", but instead, it says "the file is not here", which can be
interpreted as "the file is not here _anymore_" when comparing the
commit and its ancestor.

But as a result, there's no place to store information about _how_ the
file was removed. So, for the remote machine doing a "git pull", the
merge algorithm just sees that it's not there, and deletes it.

OTOH, after "git pull", it's rather simple to do something like

git show HEAD@{1}:your-file.txt > your-file.txt

to restore it as an untracked file. Maybe it's possible to automate
this in a script, but I have no idea how.

-- 
Matthieu Moy
http://www-verimag.imag.fr/~moy/

^ permalink raw reply

* Re: [PATCH 5/8] rerere: use ll_merge() instead of using xdl_merge()
From: Johannes Sixt @ 2010-01-17 11:52 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git
In-Reply-To: <1263721144-18605-6-git-send-email-gitster@pobox.com>

On Sonntag, 17. Januar 2010, Junio C Hamano wrote:
> This allows us to pay attention to the attribute settings and custom
> merge driver the user sets up.

I do not think that this change is necessary; I even think that it is wrong, 
in particular, custom merge drivers should *not* be used anymore.

The code path is about merging the changes between preimage and postimage into 
a file that has conflict markers (thisimage). At the time when this happens, 
all three images have already been processed by the custom merge driver.

Consider this preimage:

<foo><bar>
<<<<<<<
</bar>
=======
<baz>
text
</baz></bar>
>>>>>>>
<more text="here" />
</foo>

and a custom XML merge driver. With your change, you expect that the merge 
driver knows how to treat syntactically incorrect XML (the "<<<<<<<" 
and ">>>>>>>").

Of course, without this change, we do expect that the postimage has 
practically everything outside the conflict markers unchanged[*], otherwise 
the ll_merge() will fail.

But so would a custom XML driver that does not know how to read conflict 
markers.

[*] Which is perhaps an assumption that is easily violated. For example, the 
XML editor used to resolve the conflict could have inserted line-breaks at 
completely different spots than in the conflicted preimage.

-- Hannes

^ permalink raw reply

* Re: [RFC] Git Wiki Move
From: Matthieu Moy @ 2010-01-17 12:00 UTC (permalink / raw)
  To: J.H.; +Cc: Petr Baudis, git
In-Reply-To: <4B50F7DB.7020204@eaglescrag.net>

"J.H." <warthog19@eaglescrag.net> writes:

> Quick update - I think I've got the vast majority of the obvious and
> simple to correct problems fixed at http://git.wiki.kernel.org anyone
> want to run through and see if there's anything else that would be
> considered a show stopper?

The main page is locked, and there are some broken links formatting in
the News section: http://git.wiki.kernel.org/index.php/Main_Page#News
I'm user "Moy" there if you want to let me fix them.

You should set $wgLogo to some Git logo, among
http://git.or.cz/gitwiki/GitRelatedLogos

You can also add a few links to the sidebar, by editting:
http://git.wiki.kernel.org/index.php/MediaWiki:Sidebar

(it seems I don't have permission to do it myself). I suggest taking
the ones of the front-page:

* Starting points
** Installation|Installation
** InterfacesFrontendsAndTools|Git Tools
** GitDocumentation|Git Documentation
** GitCommunity|Git Community Support
** GitProjects|Projects using Git
** GitFaq|FAQ
** GitHosting|Git Hosting
** GitLinks|Git Links
** GitComparison|Git Compared

-- 
Matthieu Moy
http://www-verimag.imag.fr/~moy/

^ 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