Git development
 help / color / mirror / Atom feed
* Re: [PATCH 0/2] [RFD] Using gitrevisions :/search style with other operators
From: Nguyen Thai Ngoc Duy @ 2010-12-09  1:28 UTC (permalink / raw)
  To: Jakub Narebski
  Cc: Jonathan Nieder, git, Junio C Hamano, Kevin Ballard, Yann Dirson,
	Jeff King
In-Reply-To: <201012082051.09730.jnareb@gmail.com>

On Thu, Dec 9, 2010 at 2:51 AM, Jakub Narebski <jnareb@gmail.com> wrote:
> Dnia środa 8. grudnia 2010 19:06, Jonathan Nieder napisał:
>> Nguyễn Thái Ngọc Duy wrote:
>>
>> > Let's start off from where the previous discussion [1] stopped. People
>> > seem to agree ref^{/regex} is a good choice. But we have not come to
>> > conclusion how to specify the count yet. Possible suggestions are
>> >
>> >  - ref^{/foo}2
>> >  - ref^{2/foo}
>> >  - ref^{:2/foo}
>> >  - ref^{2nd/foo}
>>
>> How about
>>
>>       ref^{/foo}^^{/foo}
>>
>> ?
>
> I'll assume that there is invisible ";)" emoticon here.
>
>
> First, it would be ref^{/foo}^@^{/foo}, otherwise you would follow only
> first parent.
>
> Second, consider ref^{:nth(10)/foo} in your workaround...

Maybe we should generalize this to apply to all operators. Currently
foo~3 is expanded to foo^^^. How about ~~X (or xN) denote repeat the
last operator N times? For example, HEAD^2x3 => HEAD^2^2^2,
HEAD^{/foo}x3 => HEAD^{/foo}^{/foo}^{/foo}.
-- 
Duy

^ permalink raw reply

* Re: [PATCH 0/2] [RFD] Using gitrevisions :/search style with other operators
From: Jakub Narebski @ 2010-12-09  0:44 UTC (permalink / raw)
  To: Nguyen Thai Ngoc Duy
  Cc: git, Junio C Hamano, Kevin Ballard, Yann Dirson, Jeff King
In-Reply-To: <AANLkTi=AyCxn=dcKQQmT0_6Oc36AX6XDA4Dhhk7WLSN0@mail.gmail.com>

On Thu, 9 Dec 2010, Nguyen Thai Ngoc Duy wrote:
> 2010/12/9 Jakub Narebski <jnareb@gmail.com>:

> > I wonder if it would be possible to make :/<regex> (which looks a bit
> > like searching the index) to be an alias to --all^{/<regex>}...
> 
> It looks a bit strange to my eyes to merge normal option name with
> revision syntax. But I think it's possible. Do we allow branch/tag
> name with leading '-'?

Well, with below proposal it would simply be

  --all ^{/<regexp>}
 
> > Or if we can make ^{/<regex>} to act on revision range specified by
> > earlier commits, so for example foo..bar^{/<regex>} would work.
> 
> There is another case: branch/tag selection. Instead of looking in all
> refs, people may want to look only in nd/* branches. My branches are
> almost flat, so I don't find any use. But someone might. And we can
> solve the "all branches" case above with simply "*". The exact syntax,
> I don't know.

  --glob=heads/nd/ ^{/<regexp>}

Similarly to the --all case.

-- 
Jakub Narebski
Poland

^ permalink raw reply

* Re: [PATCH 0/2] [RFD] Using gitrevisions :/search style with other operators
From: Nguyen Thai Ngoc Duy @ 2010-12-09  0:30 UTC (permalink / raw)
  To: Jakub Narebski; +Cc: git, Junio C Hamano, Kevin Ballard, Yann Dirson, Jeff King
In-Reply-To: <201012082047.44022.jnareb@gmail.com>

2010/12/9 Jakub Narebski <jnareb@gmail.com>:
> I wonder if it would be possible to make :/<regex> (which looks a bit
> like searching the index) to be an alias to --all^{/<regex>}...

It looks a bit strange to my eyes to merge normal option name with
revision syntax. But I think it's possible. Do we allow branch/tag
name with leading '-'?

> Or if we can make ^{/<regex>} to act on revision range specified by
> earlier commits, so for example foo..bar^{/<regex>} would work.

There is another case: branch/tag selection. Instead of looking in all
refs, people may want to look only in nd/* branches. My branches are
almost flat, so I don't find any use. But someone might. And we can
solve the "all branches" case above with simply "*". The exact syntax,
I don't know.

> As to :/!<regexp> form: isn't it reserved for non-match?

It is reserved and not attached with any meaning.

> Thank you for working on this.

You're welcome. I needed to look for my branches in pu and was tired
of copy/paste.
-- 
Duy

^ permalink raw reply

* Re: [PATCH v2 4/4] describe: Delay looking up commits until searching for an inexact match
From: Anders Kaseorg @ 2010-12-08 23:47 UTC (permalink / raw)
  To: Junio C Hamano
  Cc: Jonathan Nieder, git, SZEDER Gábor, Kirill Smelkov,
	Thomas Rast
In-Reply-To: <7v7hfjkhfm.fsf@alter.siamese.dyndns.org>

On Wed, 8 Dec 2010, Junio C Hamano wrote:
> You seem to have gone in a slightly different direction with this reroll.
> I am not sure if use of hash_table in this code would actually improve
> anything (aside from the general readability and "reusing code from a good
> infrastructure is a good thing" principle), though, no matter how many
> tags you have in your repository.  In the code from the earlier round,
> lookup_commit_reference_gently call in the fallback codepath to populate
> commit->util used the *obj_hash[] to quickly look up the commits with the
> same object name already.

Yes; the problem now is that, in order to avoid calling replace_name() 
excessively, I need to resolve all multiply-tagged commits in one pass, 
before I have those commits in the obj_hash.  This could have been done 
with the linked list by deleting any commit_name from the linked list the 
first time replace_name() decides it should be superseded by a different 
commit_name, but the hash table approach seems less fragile to me.  The 
hash table also has the advantage of avoiding the O(#tags * #arguments) 
complexity when describe is given many arguments.

Let me know if you’d like me to try it the other way.

> I don't know how the above would work in the face of hash collisions.

Oh right.  I’ll fix that.

static int set_util(void *chain)
{
	struct commit_name *n;
	for (n = chain; n; n = n->next) {
		struct commit *c = lookup_commit_reference_gently(n->peeled, 1);
		if (c)
			c->util = n;
	}
	return 0;
}

> Do we know that all the archs we will be compiled on will be happy with
> this potentially unaligned access?  hash_filespec() in diffcore-rename.c
> is written in a way to avoid such an issue, and I would feel safer to 
> see this do the same.

I’ll fix that too.

static inline unsigned int hash_sha1(const unsigned char *sha1)
{
	unsigned int hash;
	memcpy(&hash, sha1, sizeof(hash));
	return hash;
}

Anders

^ permalink raw reply

* What's cooking in git.git (Dec 2010, #02; Wed, 8)
From: Junio C Hamano @ 2010-12-09  0:07 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.

--------------------------------------------------
[Graduated to "master"]

* gb/gitweb-remote-heads (2010-11-11) 11 commits
  (merged to 'next' on 2010-11-24 at 6fb4a6f)
 + git instaweb: enable remote_heads
 + gitweb: group remote heads by remote
 + gitweb: provide a routine to display (sub)sections
 + gitweb: refactor repository URL printing
 + gitweb: remotes view for a single remote
 + gitweb: allow action specialization in page header
 + gitweb: nagivation menu for tags, heads and remotes
 + gitweb: separate heads and remotes lists
 + gitweb: git_get_heads_list accepts an optional list of refs
 + gitweb: introduce remote_heads feature
 + gitweb: use fullname as hash_base in heads link

* gc/http-with-non-ascii-username-url (2010-11-14) 2 commits
  (merged to 'next' on 2010-11-24 at 08f317f)
 + Fix username and password extraction from HTTP URLs
 + t5550: test HTTP authentication and userinfo decoding

* il/remote-fd-ext (2010-11-17) 4 commits
  (merged to 'next' on 2010-11-24 at ef80cf1)
 + remote-fd/ext: finishing touches after code review
  (merged to 'next' on 2010-11-05 at 7413413)
 + git-remote-ext
 + git-remote-fd
 + Add bidirectional_transfer_loop()

* jh/notes-merge (2010-11-09) 23 commits
  (merged to 'next' on 2010-11-24 at 6218115)
 + Provide 'git merge --abort' as a synonym to 'git reset --merge'
 + cmd_merge(): Parse options before checking MERGE_HEAD
 + Provide 'git notes get-ref' to easily retrieve current notes ref
 + git notes merge: Add testcases for merging notes trees at different fanouts
 + git notes merge: Add another auto-resolving strategy: "cat_sort_uniq"
 + git notes merge: --commit should fail if underlying notes ref has moved
 + git notes merge: List conflicting notes in notes merge commit message
 + git notes merge: Manual conflict resolution, part 2/2
 + git notes merge: Manual conflict resolution, part 1/2
 + Documentation: Preliminary docs on 'git notes merge'
 + git notes merge: Add automatic conflict resolvers (ours, theirs, union)
 + git notes merge: Handle real, non-conflicting notes merges
 + builtin/notes.c: Refactor creation of notes commits.
 + git notes merge: Initial implementation handling trivial merges only
 + builtin/notes.c: Split notes ref DWIMmery into a separate function
 + notes.c: Use two newlines (instead of one) when concatenating notes
 + (trivial) t3303: Indent with tabs instead of spaces for consistency
 + notes.h/c: Propagate combine_notes_fn return value to add_note() and beyond
 + notes.h/c: Allow combine_notes functions to remove notes
 + notes.c: Reorder functions in preparation for next commit
 + notes.h: Make default_notes_ref() available in notes API
 + (trivial) notes.h: Minor documentation fixes to copy_notes()
 + notes.c: Hexify SHA1 in die() message from init_notes()

* jk/diff-CBM (2010-10-21) 1 commit
  (merged to 'next' on 2010-11-05 at 9d1ec14)
 + diff: report bogus input to -C/-M/-B

* jk/maint-decorate-01-bool (2010-11-17) 1 commit
  (merged to 'next' on 2010-11-24 at 347f73b)
 + log.decorate: accept 0/1 bool values
 (this branch is used by jk/pager-per-command.)

* jk/pager-per-command (2010-11-17) 1 commit
  (merged to 'next' on 2010-11-24 at 9ebcffc)
 + allow command-specific pagers in pager.<cmd>
 (this branch uses jk/maint-decorate-01-bool.)

* jn/gitweb-time-hires-comes-with-5.8 (2010-11-09) 1 commit
  (merged to 'next' on 2010-11-24 at 6b91b41)
 + gitweb: Time::HiRes is in core for Perl 5.8

* ks/maint-getenv-fix (2010-11-11) 1 commit
  (merged to 'next' on 2010-11-24 at fa89826)
 + setup: make sure git_dir path is in a permanent buffer, getenv(3) case
 (this branch is used by jn/getenv-poison.)

* mg/maint-tag-rfc1991 (2010-11-10) 5 commits
  (merged to 'next' on 2010-11-24 at 03864ed)
 + tag: recognize rfc1991 signatures
 + tag: factor out sig detection for tag display
 + tag: factor out sig detection for body edits
 + verify-tag: factor out signature detection
 + t/t7004-tag: test handling of rfc1991 signatures

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

* ak/describe-exact (2010-12-07) 4 commits
 - describe: Delay looking up commits until searching for an inexact match
 - describe: Store commit_names in a hash table by commit SHA1
 - describe: Do not use a flex array in struct commit_name
 - describe: Use for_each_rawref

* jc/maint-svn-info-test-fix (2010-12-06) 1 commit
  (merged to 'next' on 2010-12-08 at f821694)
 + t9119: do not compare "Text Last Updated" line from "svn info"

* jn/submodule-b-current (2010-12-05) 2 commits
  (merged to 'next' on 2010-12-08 at 33423f3)
 + git submodule: Remove now obsolete tests before cloning a repo
 + git submodule -b ... of current HEAD fails

* jc/maint-no-openssl-build-fix (2010-12-08) 1 commit
  (merged to 'next' on 2010-12-08 at e348a87)
 + Do not link with -lcrypto under NO_OPENSSL

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

* nd/index-doc (2010-09-06) 1 commit
 - doc: technical details about the index file format

Half-written but it is a good start.  I may need to give some help in
describing more recent index extensions.

* cb/ignored-paths-are-precious (2010-08-21) 1 commit
 - checkout/merge: optionally fail operation when ignored files need to be overwritten

This needs tests; also we know of longstanding bugs in related area that
needs to be addressed---they do not have to be part of this series but
their reproduction recipe would belong to the test script for this topic.

It would hurt users to make the new feature on by default, especially the
ones with subdirectories that come and go.

* jk/tag-contains (2010-07-05) 4 commits
 - Why is "git tag --contains" so slow?
 - default core.clockskew variable to one day
 - limit "contains" traversals based on commit timestamp
 - tag: speed up --contains calculation

The idea of the bottom one is probably Ok, except that the use of object
flags needs to be rethought, or at least the helper needs to be moved to
builtin/tag.c to make it clear that it should not be used outside the
current usage context.

* tr/config-doc (2010-10-24) 2 commits
 . Documentation: complete config list from other manpages
 . Documentation: Move variables from config.txt to separate file

This unfortunately heavily conflicts with patches in flight...

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

* aa/status-hilite-branch (2010-11-18) 1 commit
  (merged to 'next' on 2010-12-08 at 0291858)
 + status: show branchname with a configurable color

I am indifferent/uninterested; I don't see anything wrong with it, but I
do not find coloring the field particularly useful myself.

* ef/help-cmd-prefix (2010-11-26) 1 commit
  (merged to 'next' on 2010-12-08 at c92752e)
 + help: always suggest common-cmds if prefix of cmd

* jn/fast-import-blob-access (2010-12-03) 5 commits
  (merged to 'next' on 2010-12-08 at a42f0b3)
 + t9300: remove unnecessary use of /dev/stdin
 + fast-import: Allow cat-blob requests at arbitrary points in stream
 + fast-import: let importers retrieve blobs
 + fast-import: clarify documentation of "feature" command
 + fast-import: stricter parsing of integer options

* jn/gitweb-per-request-config (2010-11-28) 2 commits
  (merged to 'next' on 2010-12-08 at 44be9e5)
 + gitweb: document $per_request_config better
 + gitweb: selectable configurations that change with each request

* kb/diff-C-M-synonym (2010-11-29) 1 commit
 - diff: add --detect-copies-harder as a synonym for --find-copies-harder

I am not married to the approach and actually am fine with renaming the
recent "detect" to "find", which I tend to think is probably nicer.

* mg/cvsimport (2010-11-28) 3 commits
 - cvsimport.txt: document the mapping between config and options
 - cvsimport: fix the parsing of uppercase config options
 - cvsimport: partial whitespace cleanup

I was being lazy and said "Ok" to "cvsimport.capital-r" but luckily other
people injected sanity to the discussion.  Weatherbaloon patch sent, but
not queued here.

* mz/maint-rebase-stat-config (2010-11-09) 1 commit
  (merged to 'next' on 2010-12-08 at 97d4912)
 + rebase: only show stat if configured to true

* mz/pull-rebase-rebased (2010-11-13) 1 commit
  (merged to 'next' on 2010-12-08 at 99c1762)
 + Use reflog in 'pull --rebase . foo'

* nd/maint-hide-checkout-index-from-error (2010-11-28) 1 commit
  (merged to 'next' on 2010-12-08 at 1869996)
 + entry.c: remove "checkout-index" from error messages

* tf/commit-list-prefix (2010-11-26) 1 commit
 - commit: Add commit_list prefix in two function names.

* gb/web--browse (2010-12-03) 4 commits
  (merged to 'next' on 2010-12-08 at cff4009)
 + web--browse: better support for chromium
 + web--browse: support opera, seamonkey and elinks
 + web--browse: split valid_tool list
 + web--browse: coding style

The remainder of the series, which is mostly Debian specific addition, can
wait (or just left for the distro).

* ja/maint-pull-rebase-doc (2010-12-03) 1 commit
  (merged to 'next' on 2010-12-08 at 211bf89)
 + git-pull.txt: Mention branch.autosetuprebase

* js/configurable-tab (2010-11-30) 2 commits
  (merged to 'next' on 2010-12-08 at 3257365)
 + Make the tab width used for whitespace checks configurable
 + Merge branch 'js/maint-apply-tab-in-indent-fix' into HEAD
 (this branch uses js/maint-apply-tab-in-indent-fix.)

* js/maint-apply-tab-in-indent-fix (2010-11-30) 1 commit
  (merged to 'next' on 2010-12-08 at 02aedd5)
 + apply --whitespace=fix: fix tab-in-indent
 (this branch is used by js/configurable-tab.)

* pd/bash-4-completion (2010-12-01) 2 commits
 - Use the new functions to get the current cword.
 - Introduce functions from bash-completion project.

There is a "here is a better way to do this" from Jonathan, but I lost
track.

* ef/win32-dirent (2010-11-23) 6 commits
  (merged to 'next' on 2010-12-08 at 1a7169d)
 + win32: use our own dirent.h
 + msvc: opendir: handle paths ending with a slash
 + win32: dirent: handle errors
 + msvc: opendir: do not start the search
 + msvc: opendir: allocate enough memory
 + msvc: opendir: fix malloc-failure

* jk/asciidoc-update (2010-11-19) 1 commit
  (merged to 'next' on 2010-12-08 at 72ffafe)
 + docs: default to more modern toolset

* jk/maint-reflog-bottom (2010-11-21) 1 commit
  (merged to 'next' on 2010-12-08 at f5ca80a)
 + reflogs: clear flags properly in corner case

* jn/fast-import-ondemand-checkpoint (2010-11-22) 1 commit
  (merged to 'next' on 2010-12-08 at f538396)
 + fast-import: treat SIGUSR1 as a request to access objects early

* jn/maint-fast-import-object-reuse (2010-11-23) 1 commit
  (merged to 'next' on 2010-12-08 at 5d29c08)
 + fast-import: insert new object entries at start of hash bucket

* jn/maint-svn-fe (2010-12-05) 3 commits
  (merged to 'next' on 2010-12-08 at e25350b)
 + vcs-svn: fix intermittent repo_tree corruption
 + treap: make treap_insert return inserted node
 + t9010 (svn-fe): Eliminate dependency on svn perl bindings

* jn/svn-fe (2010-12-06) 18 commits
 - vcs-svn: Allow change nodes for root of tree (/)
 - vcs-svn: Implement Prop-delta handling
 - vcs-svn: Sharpen parsing of property lines
 - vcs-svn: Split off function for handling of individual properties
 - vcs-svn: Make source easier to read on small screens
 - vcs-svn: More dump format sanity checks
 - vcs-svn: Reject path nodes without Node-action
 - vcs-svn: Delay read of per-path properties
 - vcs-svn: Combine repo_replace and repo_modify functions
 - vcs-svn: Replace = Delete + Add
 - vcs-svn: handle_node: Handle deletion case early
 - vcs-svn: Use mark to indicate nodes with included text
 - vcs-svn: Unclutter handle_node by introducing have_props var
 - vcs-svn: Eliminate node_ctx.mark global
 - vcs-svn: Eliminate node_ctx.srcRev global
 - vcs-svn: Check for errors from open()
 - vcs-svn: Allow simple v3 dumps (no deltas yet)
 - vcs-svn: Error out for v3 dumps

Some RFC patches, to give them early and wider exposure.

* mz/rebase-abort-reflog-fix (2010-11-21) 1 commit
  (merged to 'next' on 2010-12-08 at adce2e1)
 + rebase --abort: do not update branch ref

* mz/rebase-i-verify (2010-11-22) 1 commit
  (merged to 'next' on 2010-12-08 at 18275df)
 + rebase: support --verify

* nd/maint-relative (2010-11-20) 1 commit
 - get_cwd_relative(): do not misinterpret root path

Will merge to 'next' soon.

* tc/format-patch-p (2010-11-23) 1 commit
  (merged to 'next' on 2010-12-08 at e8bff23)
 + format-patch: page output with --stdout

I am indifferent/uninterested; I don't see anything wrong with it,
though.

* tc/http-urls-ends-with-slash (2010-11-25) 9 commits
  (merged to 'next' on 2010-12-08 at b9a878a)
 + http-fetch: rework url handling
 + http-push: add trailing slash at arg-parse time, instead of later on
 + http-push: check path length before using it
 + http-push: Normalise directory names when pushing to some WebDAV servers
 + http-backend: use end_url_with_slash()
 + url: add str wrapper for end_url_with_slash()
 + shift end_url_with_slash() from http.[ch] to url.[ch]
 + t5550-http-fetch: add test for http-fetch
 + t5550-http-fetch: add missing '&&'

* nd/extended-sha1-relpath (2010-11-28) 2 commits
  (merged to 'next' on 2010-12-08 at 940e5e2)
 + get_sha1: support relative path ":path" syntax
 + Make prefix_path() return char* without const
 (this branch uses jn/parse-options-extra.)

* nd/maint-fix-add-typo-detection (2010-11-27) 5 commits
 - Revert "excluded_1(): support exclude files in index"
 - unpack-trees: fix sparse checkout's "unable to match directories"
 - unpack-trees: move all skip-worktree checks back to unpack_trees()
 - dir.c: add free_excludes()
 - cache.h: realign and use (1 << x) form for CE_* constants

Note that the commit that used to be at the bottom of this series
have been merged to 'master' (it was a no-op fix).

* jh/gitweb-caching (2010-12-03) 4 commits
 . gitweb: Minimal testing of gitweb caching
 . gitweb: File based caching layer (from git.kernel.org)
 . gitweb: add output buffering and associated functions
 . gitweb: Prepare for splitting gitweb

* jn/parse-options-extra (2010-12-01) 10 commits
  (merged to 'next' on 2010-12-08 at 3a3e3ac)
 + update-index: migrate to parse-options API
 + setup: save prefix (original cwd relative to toplevel) in startup_info
 + parse-options: make resuming easier after PARSE_OPT_STOP_AT_NON_OPTION
 + parse-options: allow git commands to invent new option types
 + parse-options: never suppress arghelp if LITERAL_ARGHELP is set
 + parse-options: do not infer PARSE_OPT_NOARG from option type
 + parse-options: sanity check PARSE_OPT_NOARG flag
 + parse-options: move NODASH sanity checks to parse_options_check
 + parse-options: clearer reporting of API misuse
 + parse-options: Don't call parse_options_check() so much
 (this branch is used by nd/extended-sha1-relpath.)

* nd/setup (2010-11-26) 47 commits
 - git.txt: correct where --work-tree path is relative to
 - Revert "Documentation: always respect core.worktree if set"
 - t0001: test git init when run via an alias
 - Remove all logic from get_git_work_tree()
 - setup: rework setup_explicit_git_dir()
 - setup: clean up setup_discovered_git_dir()
 - t1020-subdirectory: test alias expansion in a subdirectory
 - setup: clean up setup_bare_git_dir()
 - setup: limit get_git_work_tree()'s to explicit setup case only
 - Use git_config_early() instead of git_config() during repo setup
 - Add git_config_early()
 - rev-parse: prints --git-dir relative to user's cwd
 - git-rev-parse.txt: clarify --git-dir
 - t1510: setup case #31
 - t1510: setup case #30
 - t1510: setup case #29
 - t1510: setup case #28
 - t1510: setup case #27
 - t1510: setup case #26
 - t1510: setup case #25
 - t1510: setup case #24
 - t1510: setup case #23
 - t1510: setup case #22
 - t1510: setup case #21
 - t1510: setup case #20
 - t1510: setup case #19
 - t1510: setup case #18
 - t1510: setup case #17
 - t1510: setup case #16
 - t1510: setup case #15
 - t1510: setup case #14
 - t1510: setup case #13
 - t1510: setup case #12
 - t1510: setup case #11
 - t1510: setup case #10
 - t1510: setup case #9
 - t1510: setup case #8
 - t1510: setup case #7
 - t1510: setup case #6
 - t1510: setup case #5
 - t1510: setup case #4
 - t1510: setup case #3
 - t1510: setup case #2
 - t1510: setup case #1
 - t1510: setup case #0
 - Add t1510 and basic rules that run repo setup
 - builtins: print setup info if repo is found

* jn/git-cmd-h-bypass-setup (2010-10-22) 7 commits
  (merged to 'next' on 2010-12-08 at 0fc3158)
 + update-index -h: show usage even with corrupt index
 + merge -h: show usage even with corrupt index
 + ls-files -h: show usage even with corrupt index
 + gc -h: show usage even with broken configuration
 + commit/status -h: show usage even with broken configuration
 + checkout-index -h: show usage even in an invalid repository
 + branch -h: show usage even in an invalid repository

* yd/dir-rename (2010-10-29) 5 commits
 - Allow hiding renames of individual files involved in a directory rename.
 - Unified diff output format for bulk moves.
 - Add testcases for the --detect-bulk-moves diffcore flag.
 - Raw diff output format for bulk moves.
 - Introduce bulk-move detection in diffcore.

Yet to be rerolled.

* nd/struct-pathspec (2010-09-20) 11 commits
 - ce_path_match: drop prefix matching in favor of match_pathspec
 - Convert ce_path_match() to use struct pathspec
 - tree_entry_interesting: turn to match_pathspec if wildcard is present
 - pathspec: add tree_recursive_diff parameter
 - pathspec: mark wildcard pathspecs from the beginning
 - Move tree_entry_interesting() to tree-walk.c and export it
 - tree_entry_interesting(): remove dependency on struct diff_options
 - Convert struct diff_options to use struct pathspec
 - pathspec: cache string length when initializing pathspec
 - diff-no-index: use diff_tree_setup_paths()
 - Add struct pathspec
 (this branch is tangled with en/object-list-with-pathspec.)

This is related to something I have long been wanting to see happen.
Wait Nguyen for another round (2010-11-11).

* en/object-list-with-pathspec (2010-09-20) 8 commits
 - Add testcases showing how pathspecs are handled with rev-list --objects
 - Make rev-list --objects work together with pathspecs
 - Move tree_entry_interesting() to tree-walk.c and export it
 - tree_entry_interesting(): remove dependency on struct diff_options
 - Convert struct diff_options to use struct pathspec
 - pathspec: cache string length when initializing pathspec
 - diff-no-index: use diff_tree_setup_paths()
 - Add struct pathspec
 (this branch is tangled with nd/struct-pathspec.)

* jl/fetch-submodule-recursive (2010-11-11) 3 commits
  (merged to 'next' on 2010-12-08 at 676c4f5)
 + Submodules: Add the "fetchRecurseSubmodules" config option
 + Add the 'fetch.recurseSubmodules' config setting
 + fetch/pull: Add the --recurse-submodules option

* tr/merge-unborn-clobber (2010-08-22) 1 commit
 - Exhibit merge bug that clobbers index&WT

* ab/i18n (2010-10-07) 161 commits
 - po/de.po: complete German translation
 - po/sv.po: add Swedish translation
 - gettextize: git-bisect bisect_next_check "You need to" message
 - gettextize: git-bisect [Y/n] messages
 - gettextize: git-bisect bisect_replay + $1 messages
 - gettextize: git-bisect bisect_reset + $1 messages
 - gettextize: git-bisect bisect_run + $@ messages
 - gettextize: git-bisect die + eval_gettext messages
 - gettextize: git-bisect die + gettext messages
 - gettextize: git-bisect echo + eval_gettext message
 - gettextize: git-bisect echo + gettext messages
 - gettextize: git-bisect gettext + echo message
 - gettextize: git-bisect add git-sh-i18n
 - gettextize: git-stash drop_stash say/die messages
 - gettextize: git-stash "unknown option" message
 - gettextize: git-stash die + eval_gettext $1 messages
 - gettextize: git-stash die + eval_gettext $* messages
 - gettextize: git-stash die + eval_gettext messages
 - gettextize: git-stash die + gettext messages
 - gettextize: git-stash say + gettext messages
 - gettextize: git-stash echo + gettext message
 - gettextize: git-stash add git-sh-i18n
 - gettextize: git-submodule "blob" and "submodule" messages
 - gettextize: git-submodule "path not initialized" message
 - gettextize: git-submodule "[...] path is ignored" message
 - gettextize: git-submodule "Entering [...]" message
 - gettextize: git-submodule $errmsg messages
 - gettextize: git-submodule "Submodule change[...]" messages
 - gettextize: git-submodule "cached cannot be used" message
 - gettextize: git-submodule $update_module say + die messages
 - gettextize: git-submodule die + eval_gettext messages
 - gettextize: git-submodule say + eval_gettext messages
 - gettextize: git-submodule echo + eval_gettext messages
 - gettextize: git-submodule add git-sh-i18n
 - gettextize: git-pull "rebase against" / "merge with" messages
 - gettextize: git-pull "[...] not currently on a branch" message
 - gettextize: git-pull "You asked to pull" message
 - gettextize: git-pull split up "no candidate" message
 - gettextize: git-pull eval_gettext + warning message
 - gettextize: git-pull eval_gettext + die message
 - gettextize: git-pull die messages
 - gettextize: git-pull add git-sh-i18n
 - gettext docs: add "Testing marked strings" section to po/README
 - gettext docs: the Git::I18N Perl interface
 - gettext docs: the git-sh-i18n.sh Shell interface
 - gettext docs: the gettext.h C interface
 - gettext docs: add "Marking strings for translation" section in po/README
 - gettext docs: add a "Testing your changes" section to po/README
 - po/pl.po: add Polish translation
 - po/hi.po: add Hindi Translation
 - po/en_GB.po: add British English translation
 - po/de.po: add German translation
 - Makefile: only add gettext tests on XGETTEXT_INCLUDE_TESTS=YesPlease
 - gettext docs: add po/README file documenting Git's gettext
 - gettextize: git-am printf(1) message to eval_gettext
 - gettextize: git-am core say messages
 - gettextize: git-am "Apply?" message
 - gettextize: git-am clean_abort messages
 - gettextize: git-am cannot_fallback messages
 - gettextize: git-am die messages
 - gettextize: git-am eval_gettext messages
 - gettextize: git-am multi-line getttext $msg; echo
 - gettextize: git-am one-line gettext $msg; echo
 - gettextize: git-am add git-sh-i18n
 - gettext tests: add GETTEXT_POISON tests for shell scripts
 - gettext tests: add GETTEXT_POISON support for shell scripts
 - Makefile: MSGFMT="msgfmt --check" under GNU_GETTEXT
 - Makefile: add GNU_GETTEXT, set when we expect GNU gettext
 - gettextize: git-shortlog basic messages
 - gettextize: git-revert split up "could not revert/apply" message
 - gettextize: git-revert literal "me" messages
 - gettextize: git-revert "Your local changes" message
 - gettextize: git-revert basic messages
 - gettextize: git-notes "Refusing to %s notes in %s" message
 - gettextize: git-notes GIT_NOTES_REWRITE_MODE error message
 - gettextize: git-notes basic commands
 - gettextize: git-gc "Auto packing the repository" message
 - gettextize: git-gc basic messages
 - gettextize: git-describe basic messages
 - gettextize: git-clean clean.requireForce messages
 - gettextize: git-clean basic messages
 - gettextize: git-bundle basic messages
 - gettextize: git-archive basic messages
 - gettextize: git-status "renamed: " message
 - gettextize: git-status "Initial commit" message
 - gettextize: git-status "Changes to be committed" message
 - gettextize: git-status shortstatus messages
 - gettextize: git-status "nothing to commit" messages
 - gettextize: git-status basic messages
 - gettextize: git-push "prevent you from losing" message
 - gettextize: git-push basic messages
 - gettextize: git-tag tag_template message
 - gettextize: git-tag basic messages
 - gettextize: git-reset "Unstaged changes after reset" message
 - gettextize: git-reset reset_type_names messages
 - gettextize: git-reset basic messages
 - gettextize: git-rm basic messages
 - gettextize: git-mv "bad" messages
 - gettextize: git-mv basic messages
 - gettextize: git-merge "Wonderful" message
 - gettextize: git-merge "You have not concluded your merge" messages
 - gettextize: git-merge "Updating %s..%s" message
 - gettextize: git-merge basic messages
 - gettextize: git-log "--OPT does not make sense" messages
 - gettextize: git-log basic messages
 - gettextize: git-grep "--open-files-in-pager" message
 - gettextize: git-grep basic messages
 - gettextize: git-fetch split up "(non-fast-forward)" message
 - gettextize: git-fetch update_local_ref messages
 - gettextize: git-fetch formatting messages
 - gettextize: git-fetch basic messages
 - gettextize: git-diff basic messages
 - gettextize: git-commit advice messages
 - gettextize: git-commit "enter the commit message" message
 - gettextize: git-commit print_summary messages
 - gettextize: git-commit formatting messages
 - gettextize: git-commit "middle of a merge" message
 - gettextize: git-commit basic messages
 - gettextize: git-checkout "Switched to a .. branch" message
 - gettextize: git-checkout "HEAD is now at" message
 - gettextize: git-checkout describe_detached_head messages
 - gettextize: git-checkout: our/their version message
 - gettextize: git-checkout basic messages
 - gettextize: git-branch "(no branch)" message
 - gettextize: git-branch "git branch -v" messages
 - gettextize: git-branch "Deleted branch [...]" message
 - gettextize: git-branch "remote branch '%s' not found" message
 - gettextize: git-branch basic messages
 - gettextize: git-add refresh_index message
 - gettextize: git-add "remove '%s'" message
 - gettextize: git-add "pathspec [...] did not match" message
 - gettextize: git-add "Use -f if you really want" message
 - gettextize: git-add "no files added" message
 - gettextize: git-add basic messages
 - gettextize: git-clone "Cloning into" message
 - gettextize: git-clone basic messages
 - gettext tests: test message re-encoding under C
 - po/is.po: add Icelandic translation
 - gettext tests: mark a test message as not needing translation
 - gettext tests: test re-encoding with a UTF-8 msgid under Shell
 - gettext tests: test message re-encoding under Shell
 - gettext tests: add detection for is_IS.ISO-8859-1 locale
 - gettext tests: test if $VERSION exists before using it
 - gettextize: git-init "Initialized [...] repository" message
 - gettextize: git-init basic messages
 - gettext tests: skip lib-gettext.sh tests under GETTEXT_POISON
 - gettext tests: add GETTEXT_POISON=YesPlease Makefile parameter
 - gettext.c: use libcharset.h instead of langinfo.h when available
 - gettext.c: work around us not using setlocale(LC_CTYPE, "")
 - builtin.h: Include gettext.h
 - Makefile: use variables and shorter lines for xgettext
 - Makefile: tell xgettext(1) that our source is in UTF-8
 - Makefile: provide a --msgid-bugs-address to xgettext(1)
 - Makefile: A variable for options used by xgettext(1) calls
 - gettext tests: locate i18n lib&data correctly under --valgrind
 - gettext: setlocale(LC_CTYPE, "") breaks Git's C function assumptions
 - gettext tests: rename test to work around GNU gettext bug
 - gettext: add infrastructure for translating Git with gettext
 - builtin: use builtin.h for all builtin commands
 - tests: use test_cmp instead of piping to diff(1)
 - t7004-tag.sh: re-arrange git tag comment for clarity

It is getting ridiculously painful to keep re-resolving the conflicts with
other topics in flight, even with the help with rerere.

Needs a bit more minor work to get the basic code structure right.

^ permalink raw reply

* Re: missing tags!
From: layer @ 2010-12-09  0:05 UTC (permalink / raw)
  To: Jeff King; +Cc: git
In-Reply-To: <20101208201829.GA15938@sigill.intra.peff.net>

Jeff King <peff@peff.net> wrote:

>> On Wed, Dec 08, 2010 at 11:44:35AM -0800, layer wrote:
>> 
>> > I have a repo to which I push to frequently.  For each release of the
>> > software from this repo, I create an annotated tag and push it to this
>> > repo.  I noticed yesterday that he has a single tag in it, when it
>> > should have 100+.  The tag there was the last one I pushed to it.
>> > 
>> > The missing tags were created with
>> > 
>> >   git tag -a -m "release 4.2rm t1" release42rm_t1 HEAD
>> > 
>> > and pushed to the (bare) repo in question with
>> > 
>> >   git push origin release42rm_t1
>> > 
>> > I cannot imagine how the tags got deleted, and I'm looking for some
>> > guidance.
>> 
>> How did you verify that the tags were deleted? Are you sure they are not
>> just packed?

Ack.  I didn't know about packed tags.

Thanks, and sorry for the noise.

Kevin

^ permalink raw reply

* Re: [PATCH] git submodule -b ... of current HEAD fails
From: Jonathan Nieder @ 2010-12-08 23:45 UTC (permalink / raw)
  To: Jens Lehmann
  Cc: git, Junio C Hamano, Klaus Ethgen, Sven Verdoolaege, mlevedahl
In-Reply-To: <4D001292.3020503@web.de>

Jens Lehmann wrote:
> --- a/git-submodule.sh
> +++ b/git-submodule.sh
> @@ -241,7 +241,9 @@ cmd_add()
>  			# ash fails to wordsplit ${branch:+-b "$branch"...}
>  			case "$branch" in
>  			'') git checkout -f -q ;;
> -			?*) git checkout -f -q -b "$branch" "origin/$branch" ;;
> +			?*) if [ "$(git branch)" != "* $branch"  ]; then

Agh.  The command to use is "git symbolic-ref -q HEAD", I suppose.

Maybe we can simplify by relying on "git clone".

Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
---
 git-submodule.sh           |   16 ++++++----------
 t/t7400-submodule-basic.sh |    8 +++++++-
 2 files changed, 13 insertions(+), 11 deletions(-)

diff --git a/git-submodule.sh b/git-submodule.sh
index d937f0b..6fd09e7 100755
--- a/git-submodule.sh
+++ b/git-submodule.sh
@@ -219,17 +219,13 @@ cmd_add()
 		esac
 		git config submodule."$path".url "$url"
 	else
-
-		module_clone "$path" "$realrepo" "$reference" || exit
+		brancharg=${branch:+"-b $(git rev-parse --sq-quote "$branch")"}
+		refarg=${reference:+"$(git rev-parse --sq-quote "$reference")"}
 		(
-			clear_local_git_env
-			cd "$path" &&
-			# ash fails to wordsplit ${branch:+-b "$branch"...}
-			case "$branch" in
-			'') git checkout -f -q ;;
-			?*) git checkout -f -q -b "$branch" "origin/$branch" ;;
-			esac
-		) || die "Unable to checkout submodule '$path'"
+			export realrepo path &&
+			eval "git clone $brancharg $refarg" '"$realrepo" "$path"'
+		) ||
+		die "Clone of '$realrepo' into submodule path '$path' failed"
 	fi
 
 	git add $force "$path" ||
diff --git a/t/t7400-submodule-basic.sh b/t/t7400-submodule-basic.sh
index 2c49db9..77088cc 100755
--- a/t/t7400-submodule-basic.sh
+++ b/t/t7400-submodule-basic.sh
@@ -114,7 +114,6 @@ test_expect_success 'submodule add --branch' '
 	echo "refs/heads/initial" >expect-head &&
 	cat <<-\EOF >expect-heads &&
 	refs/heads/initial
-	refs/heads/master
 	EOF
 	>empty &&
 
@@ -131,6 +130,13 @@ test_expect_success 'submodule add --branch' '
 	test_cmp empty untracked
 '
 
+test_expect_success 'submodule add --branch succeeds even when branch is at HEAD' '
+	(
+		cd addtest &&
+		git submodule add -b master "$submodurl" submod-existing-branch
+	)
+'
+
 test_expect_success 'submodule add with ./ in path' '
 	echo "refs/heads/master" >expect &&
 	>empty &&

^ permalink raw reply related

* Re: [BUG] git-add doesn't apply filepatterns to tracked files
From: Kevin Ballard @ 2010-12-08 23:27 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git list
In-Reply-To: <7vipz3j228.fsf@alter.siamese.dyndns.org>

On Dec 8, 2010, at 3:07 PM, Junio C Hamano wrote:

> Kevin Ballard <kevin@sb.org> writes:
> 
>> It seems that git-add doesn't match filepatterns against tracked files,
> 
> This is an issue known for a long time (and the one I had been bitching
> about every time I had a chance).  Tracked ones obey diff-index pathspec
> rules (leading path match only) while untracked ones use gitignore
> pathspec rules.

If I understand you correctly, you're saying tracked files don't understand
patterns because git-diff-index doesn't handle patterns? Is there some reason
that git-diff-index doesn't support patterns? I tried a handful of commands
and here's the pattern-matching behavior I saw:

git-add: patterns match untracked, but not tracked
git-rm: patterns match tracked files, command doesn't work on untracked
git-status: patterns match untracked, but not tracked
git-ls-files: patterns match tracked, command doesn't work on untracked
git-ls-tree: no pattern support
git-check-attr: no pattern support

Documentation is a bit sporadic here as well. git-add lists <filepattern>
in its synopsis and options and defines this as supporting
"fileglobs". No mention whatsoever of the tracked file limitation.
git-rm only lists <file> in synopsis/options, but does document this
as being a "fileglob". git-status uses <pathspec> in the synopsis, and
doesn't even document this in the options. It only makes a reference
in the description, calling it "paths". git-ls-files calls it <file>
in both synopsis and options, and makes no mention whatsoever of globs.
git-ls-tree uses <path> in both synopsis/options, but explicitly claims
that this is really a pattern in the option documentation. Curious,
given its complete lack of pattern matching. git-check-attr uses
<list-of-paths> in the synopsis, with no mention in the options.

Overall, there's a few problems here. The first is that git-add and
git-ls-files apply the git-diff-index rules for tracked files, but
apply actual patterns to untracked files. The second is the documentation
is inconsistent, both in the name of the argument, and in making it
clear which commands actually support patterns (plus the documentation
for git-ls-tree is explicitly wrong about pattern support). The third
is we're inconsistent in which commands support patterns at all.

-Kevin Ballard

^ permalink raw reply

* [PATCH] git submodule -b ... of current HEAD fails
From: Jens Lehmann @ 2010-12-08 23:19 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Jonathan Nieder, Klaus Ethgen, Sven Verdoolaege,
	mlevedahl
In-Reply-To: <4CFFFA05.6070609@web.de>

	git submodule add -b $branch $repository

fails when HEAD already points to $branch in $repository.

When the freshly cloned submodules HEAD is the same as the checked out
branch, it doesn't make sense to update it again as "git checkout -b"
would fail with »fatal: git checkout: branch $branch already exists«.

Reported-by: Klaus Ethgen <Klaus@Ethgen.de>
Thanks-to: Jonathan Nieder <jrnieder@gmail.com>
Signed-off-by: Jens Lehmann <Jens.Lehmann@web.de>
---

Am 08.12.2010 22:35, schrieb Jens Lehmann:
> Am 07.12.2010 23:57, schrieb Junio C Hamano:
>> Jens Lehmann <Jens.Lehmann@web.de> writes:
>>
>>> Nope, these lines date back to the time before I got involved in the
>>> submodule business ... Seems like this "git checkout" was added in
>>> March 2008 by Mark Levedahl (CCed), maybe he can shed some light on
>>> that.
>>>
>>> But to me your change looks good, so feel free to add:
>>> Acked-by: Jens Lehmann <Jens.Lehmann@web.de>
>>
>> Does either of you want to add a test for this?
> 
> Will do.

And as it happens from time to time, while writing the test you find
out that the first attempt to fix the bug didn't work as expected ...

 git-submodule.sh           |    4 +++-
 t/t7400-submodule-basic.sh |    7 +++++++
 2 files changed, 10 insertions(+), 1 deletions(-)

diff --git a/git-submodule.sh b/git-submodule.sh
index 33bc41f..bf2803f 100755
--- a/git-submodule.sh
+++ b/git-submodule.sh
@@ -241,7 +241,9 @@ cmd_add()
 			# ash fails to wordsplit ${branch:+-b "$branch"...}
 			case "$branch" in
 			'') git checkout -f -q ;;
-			?*) git checkout -f -q -b "$branch" "origin/$branch" ;;
+			?*) if [ "$(git branch)" != "* $branch"  ]; then
+				git checkout -f -q -b "$branch" "origin/$branch"
+			fi ;;
 			esac
 		) || die "Unable to checkout submodule '$path'"
 	fi
diff --git a/t/t7400-submodule-basic.sh b/t/t7400-submodule-basic.sh
index 782b0a3..e224da4 100755
--- a/t/t7400-submodule-basic.sh
+++ b/t/t7400-submodule-basic.sh
@@ -131,6 +131,13 @@ test_expect_success 'submodule add --branch' '
 	test_cmp empty untracked
 '

+test_expect_success 'submodule add --branch succeeds even when branch is at HEAD' '
+	(
+		cd addtest &&
+		git submodule add -b master "$submodurl" submod-existing-branch
+	)
+'
+
 test_expect_success 'submodule add with ./ in path' '
 	echo "refs/heads/master" >expect &&
 	>empty &&
-- 
1.7.3.3.580.ged75d

^ permalink raw reply related

* Re: [BUG] git-add doesn't apply filepatterns to tracked files
From: Junio C Hamano @ 2010-12-08 23:07 UTC (permalink / raw)
  To: Kevin Ballard; +Cc: git list
In-Reply-To: <47FCD78C-5D8C-4FA5-88DC-26FDCC7361AD@sb.org>

Kevin Ballard <kevin@sb.org> writes:

> It seems that git-add doesn't match filepatterns against tracked files,

This is an issue known for a long time (and the one I had been bitching
about every time I had a chance).  Tracked ones obey diff-index pathspec
rules (leading path match only) while untracked ones use gitignore
pathspec rules.

^ permalink raw reply

* [BUG] git-add doesn't apply filepatterns to tracked files
From: Kevin Ballard @ 2010-12-08 23:01 UTC (permalink / raw)
  To: git list

Ran across a rather bizarre bug today while trying to help someone in #git.
It seems that git-add doesn't match filepatterns against tracked files,
only against untracked files. Other tested commands (such as git-rm and
git-ls-files) are happy to match tracked files, but not git-add.

% git --version
git version 1.7.3.3.576.gd872
% ls -a
./       ../      .git/    bar.txt  foo.txt
% git status --short
 M foo.txt
?? bar.txt
% git add '*.txt'
% git status --short
A  bar.txt
 M foo.txt

There are no .gitignores in play here.

I haven't had time to investigate the source yet, as I'm still at work.

-Kevin Ballard

^ permalink raw reply

* Re: Push to all repositories
From: Kevin Sheedy @ 2010-12-08 22:59 UTC (permalink / raw)
  To: git
In-Reply-To: <20101208180049.GC5687@burratino>


I would like (1), have the code changed under my feet.
Obviously, this would exclude my locally modified files. Also, a user could
lock local files or turn off automatic updates altogether.

Clearcase dynamic views are a lovely way to collaborate with a team (despite
their many technical problems). They remove the need to perform manual
updates. Teams just stay in sync by default. There are fewer code
collisions. Problems get spotted and fixed sooner. It you don't want
something changed under your feet, that's supported too.

I guess the question is: "By default, do you want the latest code or not?"
(This is similar to how the Google Chrome Browser defaults to giving you
updates. When you're not looking, it just updates itself in the background.
You just trust that it will use this power wisely, and it does.)

It could work something like this:
Every time a repository is cloned, the location of the new clone would be
added to the repository. When a user does a push, it gets pushed out to
everyone repository on this list. Each user could retain total control over
these updates.

Do you see any reason why this couldn't be added as an enhancement to git?

Cheers
Kev
-- 
View this message in context: http://git.661346.n2.nabble.com/Push-to-all-repositories-tp5816069p5817177.html
Sent from the git mailing list archive at Nabble.com.

^ permalink raw reply

* [PATCH 2/6] Convert diffcore-rename's rename_dst to the new sorted-array API.
From: Yann Dirson @ 2010-12-08 22:51 UTC (permalink / raw)
  To: git; +Cc: Yann Dirson
In-Reply-To: <1291848695-24601-1-git-send-email-ydirson@altern.org>

The sorted-array API splits search and insert into two separated
functions, which makes the caller code more clear.

Signed-off-by: Yann Dirson <ydirson@altern.org>
---
 diffcore-rename.c |   62 ++++++++++++++++++-----------------------------------
 1 files changed, 21 insertions(+), 41 deletions(-)

diff --git a/diffcore-rename.c b/diffcore-rename.c
index df41be5..ca3f54c 100644
--- a/diffcore-rename.c
+++ b/diffcore-rename.c
@@ -5,52 +5,32 @@
 #include "diff.h"
 #include "diffcore.h"
 #include "hash.h"
+#include "sorted-array.h"
 
 /* Table of rename/copy destinations */
 
-static struct diff_rename_dst {
+struct diff_rename_dst {
 	struct diff_filespec *two;
 	struct diff_filepair *pair;
-} *rename_dst;
-static int rename_dst_nr, rename_dst_alloc;
+};
 
-static struct diff_rename_dst *locate_rename_dst(struct diff_filespec *two,
-						 int insert_ok)
+static int rename_dst_cmp(struct diff_filespec *ref_spec, struct diff_rename_dst *elem)
 {
-	int first, last;
-
-	first = 0;
-	last = rename_dst_nr;
-	while (last > first) {
-		int next = (last + first) >> 1;
-		struct diff_rename_dst *dst = &(rename_dst[next]);
-		int cmp = strcmp(two->path, dst->two->path);
-		if (!cmp)
-			return dst;
-		if (cmp < 0) {
-			last = next;
-			continue;
-		}
-		first = next+1;
-	}
-	/* not found */
-	if (!insert_ok)
-		return NULL;
-	/* insert to make it at "first" */
-	if (rename_dst_alloc <= rename_dst_nr) {
-		rename_dst_alloc = alloc_nr(rename_dst_alloc);
-		rename_dst = xrealloc(rename_dst,
-				      rename_dst_alloc * sizeof(*rename_dst));
-	}
-	rename_dst_nr++;
-	if (first < rename_dst_nr)
-		memmove(rename_dst + first + 1, rename_dst + first,
-			(rename_dst_nr - first - 1) * sizeof(*rename_dst));
-	rename_dst[first].two = alloc_filespec(two->path);
-	fill_filespec(rename_dst[first].two, two->sha1, two->mode);
-	rename_dst[first].pair = NULL;
-	return &(rename_dst[first]);
+	return strcmp(ref_spec->path, elem->two->path);
+}
+static void rename_dst_init(struct diff_rename_dst *elem, struct diff_filespec *ref_spec)
+{
+	elem->two = alloc_filespec(ref_spec->path);
+	fill_filespec(elem->two, ref_spec->sha1, ref_spec->mode);
+	elem->pair = NULL;
 }
+declare_sorted_array(static, struct diff_rename_dst, rename_dst);
+declare_sorted_array_search_elem(static, struct diff_rename_dst, locate_rename_dst,
+				 struct diff_filespec *,
+				 rename_dst, rename_dst_cmp);
+declare_sorted_array_insert_checkbool(static, struct diff_rename_dst, register_rename_dst,
+				      struct diff_filespec *, _gen_locate_rename_dst,
+				      rename_dst, rename_dst_cmp, rename_dst_init);
 
 /* Table of rename/copy src files */
 static struct diff_rename_src {
@@ -437,7 +417,7 @@ void diffcore_rename(struct diff_options *options)
 				 strcmp(options->single_follow, p->two->path))
 				continue; /* not interested */
 			else
-				locate_rename_dst(p->two, 1);
+				register_rename_dst(p->two);
 		}
 		else if (!DIFF_FILE_VALID(p->two)) {
 			/*
@@ -582,7 +562,7 @@ void diffcore_rename(struct diff_options *options)
 			 * not been turned into a rename/copy already.
 			 */
 			struct diff_rename_dst *dst =
-				locate_rename_dst(p->two, 0);
+				locate_rename_dst(p->two);
 			if (dst && dst->pair) {
 				diff_q(&outq, dst->pair);
 				pair_to_free = p;
@@ -613,7 +593,7 @@ void diffcore_rename(struct diff_options *options)
 			if (DIFF_PAIR_BROKEN(p)) {
 				/* broken delete */
 				struct diff_rename_dst *dst =
-					locate_rename_dst(p->one, 0);
+					locate_rename_dst(p->one);
 				if (dst && dst->pair)
 					/* counterpart is now rename/copy */
 					pair_to_free = p;
-- 
1.7.2.3

^ permalink raw reply related

* [PATCH 4/6] Convert pack-objects.c to the new sorted-array API.
From: Yann Dirson @ 2010-12-08 22:51 UTC (permalink / raw)
  To: git; +Cc: Yann Dirson
In-Reply-To: <1291848695-24601-1-git-send-email-ydirson@altern.org>

In this file the "list size" variable was named in a non-standard way.
The new API forces to use a more common convention.

Signed-off-by: Yann Dirson <ydirson@altern.org>
---
 builtin/pack-objects.c |   50 +++++++++++++----------------------------------
 1 files changed, 14 insertions(+), 36 deletions(-)

diff --git a/builtin/pack-objects.c b/builtin/pack-objects.c
index f027b3a..c26175c 100644
--- a/builtin/pack-objects.c
+++ b/builtin/pack-objects.c
@@ -16,6 +16,7 @@
 #include "list-objects.h"
 #include "progress.h"
 #include "refs.h"
+#include "sorted-array.h"
 
 #ifndef NO_PTHREADS
 #include <pthread.h>
@@ -871,45 +872,22 @@ static void add_pbase_object(struct tree_desc *tree,
 	}
 }
 
-static unsigned *done_pbase_paths;
-static int done_pbase_paths_num;
-static int done_pbase_paths_alloc;
-static int done_pbase_path_pos(unsigned hash)
+static int unsigned_cmp(unsigned ref, unsigned *elem)
 {
-	int lo = 0;
-	int hi = done_pbase_paths_num;
-	while (lo < hi) {
-		int mi = (hi + lo) / 2;
-		if (done_pbase_paths[mi] == hash)
-			return mi;
-		if (done_pbase_paths[mi] < hash)
-			hi = mi;
-		else
-			lo = mi + 1;
-	}
-	return -lo-1;
+	if (ref == *elem)
+		return 0;
+	if (ref < *elem)
+		return -1;
+	return 1;
 }
-
-static int check_pbase_path(unsigned hash)
+static void unsigned_init(unsigned *elem, unsigned ref)
 {
-	int pos = (!done_pbase_paths) ? -1 : done_pbase_path_pos(hash);
-	if (0 <= pos)
-		return 1;
-	pos = -pos - 1;
-	if (done_pbase_paths_alloc <= done_pbase_paths_num) {
-		done_pbase_paths_alloc = alloc_nr(done_pbase_paths_alloc);
-		done_pbase_paths = xrealloc(done_pbase_paths,
-					    done_pbase_paths_alloc *
-					    sizeof(unsigned));
-	}
-	done_pbase_paths_num++;
-	if (pos < done_pbase_paths_num)
-		memmove(done_pbase_paths + pos + 1,
-			done_pbase_paths + pos,
-			(done_pbase_paths_num - pos - 1) * sizeof(unsigned));
-	done_pbase_paths[pos] = hash;
-	return 0;
+	*elem = ref;
 }
+declare_sorted_array(static, unsigned, done_pbase_paths);
+declare_sorted_array_insertonly_checkbool(static, unsigned, check_pbase_path,
+					  unsigned,
+					  done_pbase_paths, unsigned_cmp, unsigned_init);
 
 static void add_preferred_base_object(const char *name)
 {
@@ -987,7 +965,7 @@ static void cleanup_preferred_base(void)
 
 	free(done_pbase_paths);
 	done_pbase_paths = NULL;
-	done_pbase_paths_num = done_pbase_paths_alloc = 0;
+	done_pbase_paths_nr = done_pbase_paths_alloc = 0;
 }
 
 static void check_object(struct object_entry *entry)
-- 
1.7.2.3

^ permalink raw reply related

* [PATCH 3/6] Convert diffcore-rename's rename_src to the new sorted-array API.
From: Yann Dirson @ 2010-12-08 22:51 UTC (permalink / raw)
  To: git; +Cc: Yann Dirson
In-Reply-To: <1291848695-24601-1-git-send-email-ydirson@altern.org>

There was no compelling reason to pass separately two members of a
single struct to the insert function.  That's a happy coincidence.

Signed-off-by: Yann Dirson <ydirson@altern.org>
---
 diffcore-rename.c |   53 ++++++++++++++++-------------------------------------
 1 files changed, 16 insertions(+), 37 deletions(-)

diff --git a/diffcore-rename.c b/diffcore-rename.c
index ca3f54c..f7afdeb 100644
--- a/diffcore-rename.c
+++ b/diffcore-rename.c
@@ -33,46 +33,25 @@ declare_sorted_array_insert_checkbool(static, struct diff_rename_dst, register_r
 				      rename_dst, rename_dst_cmp, rename_dst_init);
 
 /* Table of rename/copy src files */
-static struct diff_rename_src {
+
+struct diff_rename_src {
 	struct diff_filespec *one;
 	unsigned short score; /* to remember the break score */
-} *rename_src;
-static int rename_src_nr, rename_src_alloc;
+};
 
-static struct diff_rename_src *register_rename_src(struct diff_filespec *one,
-						   unsigned short score)
+static int rename_src_cmp(struct diff_filepair *ref_pair, struct diff_rename_src *elem)
 {
-	int first, last;
-
-	first = 0;
-	last = rename_src_nr;
-	while (last > first) {
-		int next = (last + first) >> 1;
-		struct diff_rename_src *src = &(rename_src[next]);
-		int cmp = strcmp(one->path, src->one->path);
-		if (!cmp)
-			return src;
-		if (cmp < 0) {
-			last = next;
-			continue;
-		}
-		first = next+1;
-	}
-
-	/* insert to make it at "first" */
-	if (rename_src_alloc <= rename_src_nr) {
-		rename_src_alloc = alloc_nr(rename_src_alloc);
-		rename_src = xrealloc(rename_src,
-				      rename_src_alloc * sizeof(*rename_src));
-	}
-	rename_src_nr++;
-	if (first < rename_src_nr)
-		memmove(rename_src + first + 1, rename_src + first,
-			(rename_src_nr - first - 1) * sizeof(*rename_src));
-	rename_src[first].one = one;
-	rename_src[first].score = score;
-	return &(rename_src[first]);
+	return strcmp(ref_pair->one->path, elem->one->path);
+}
+static void rename_src_init(struct diff_rename_src *elem, struct diff_filepair *ref_pair)
+{
+	elem->one = ref_pair->one;
+	elem->score = ref_pair->score;
 }
+declare_sorted_array(static, struct diff_rename_src, rename_src);
+declare_sorted_array_insertonly_checkbool(static, struct diff_rename_src, register_rename_src,
+					  struct diff_filepair *,
+					  rename_src, rename_src_cmp, rename_src_init);
 
 static int basename_same(struct diff_filespec *src, struct diff_filespec *dst)
 {
@@ -429,7 +408,7 @@ void diffcore_rename(struct diff_options *options)
 			 */
 			if (p->broken_pair && !p->score)
 				p->one->rename_used++;
-			register_rename_src(p->one, p->score);
+			register_rename_src(p);
 		}
 		else if (detect_rename == DIFF_DETECT_COPY) {
 			/*
@@ -437,7 +416,7 @@ void diffcore_rename(struct diff_options *options)
 			 * one, to indicate ourselves as a user.
 			 */
 			p->one->rename_used++;
-			register_rename_src(p->one, p->score);
+			register_rename_src(p);
 		}
 	}
 	if (rename_dst_nr == 0 || rename_src_nr == 0)
-- 
1.7.2.3

^ permalink raw reply related

* [PATCH 6/6] [RFC] subvert sorted-array to replace binary-search in unpack-objects.
From: Yann Dirson @ 2010-12-08 22:51 UTC (permalink / raw)
  To: git; +Cc: Yann Dirson
In-Reply-To: <1291848695-24601-1-git-send-email-ydirson@altern.org>

Signed-off-by: Yann Dirson <ydirson@altern.org>
---
 builtin/unpack-objects.c |   40 +++++++++++++++++++++++++---------------
 1 files changed, 25 insertions(+), 15 deletions(-)

diff --git a/builtin/unpack-objects.c b/builtin/unpack-objects.c
index f63973c..6d7d113 100644
--- a/builtin/unpack-objects.c
+++ b/builtin/unpack-objects.c
@@ -11,6 +11,7 @@
 #include "progress.h"
 #include "decorate.h"
 #include "fsck.h"
+#include "sorted-array.h"
 
 static int dry_run, quiet, recover, has_errors, strict;
 static const char unpack_usage[] = "git unpack-objects [-n] [-q] [-r] [--strict] < pack-file";
@@ -157,7 +158,24 @@ struct obj_info {
 #define FLAG_OPEN (1u<<20)
 #define FLAG_WRITTEN (1u<<21)
 
-static struct obj_info *obj_list;
+/*
+ * FIXME: obj_info is a sorted array, but we read it as a whole, we
+ * don't need insertion features.  This allows us to abuse unused
+ * obj_info_nr later as a means of specifying an upper bound for
+ * binary search.  obj_info_alloc shall be eliminated by the compiler
+ * as unused.
+ */
+static int obj_info_cmp(off_t ref, struct obj_info *elem)
+{
+	if (ref == elem->offset)
+		return 0;
+	if (ref < elem->offset)
+		return -1;
+	return 1;
+}
+declare_sorted_array(static, struct obj_info, obj_list);
+declare_sorted_array_search_check(static, struct obj_info, obj_list_check,
+				  off_t, obj_list, obj_info_cmp);
 static unsigned nr_objects;
 
 /*
@@ -356,7 +374,7 @@ static void unpack_delta_entry(enum object_type type, unsigned long delta_size,
 		unsigned base_found = 0;
 		unsigned char *pack, c;
 		off_t base_offset;
-		unsigned lo, mid, hi;
+		int pos;
 
 		pack = fill(1);
 		c = *pack;
@@ -380,19 +398,11 @@ static void unpack_delta_entry(enum object_type type, unsigned long delta_size,
 			free(delta_data);
 			return;
 		}
-		lo = 0;
-		hi = nr;
-		while (lo < hi) {
-			mid = (lo + hi)/2;
-			if (base_offset < obj_list[mid].offset) {
-				hi = mid;
-			} else if (base_offset > obj_list[mid].offset) {
-				lo = mid + 1;
-			} else {
-				hashcpy(base_sha1, obj_list[mid].sha1);
-				base_found = !is_null_sha1(base_sha1);
-				break;
-			}
+		obj_list_nr = nr; /* kludge to bound the search */
+		pos = obj_list_check(base_offset);
+		if (pos >= 0) {
+			hashcpy(base_sha1, obj_list[pos].sha1);
+			base_found = !is_null_sha1(base_sha1);
 		}
 		if (!base_found) {
 			/*
-- 
1.7.2.3

^ permalink raw reply related

* [PATCH 5/6] Use sorted-array API for commit.c's commit_graft.
From: Yann Dirson @ 2010-12-08 22:51 UTC (permalink / raw)
  To: git; +Cc: Yann Dirson
In-Reply-To: <1291848695-24601-1-git-send-email-ydirson@altern.org>

Factorizing code fixes off-by-one error in the duplicated code (caused
mostly harmless anticipated growing of the array).

Signed-off-by: Yann Dirson <ydirson@altern.org>
---
 commit.c |   55 +++++++++++++++++++++----------------------------------
 1 files changed, 21 insertions(+), 34 deletions(-)

diff --git a/commit.c b/commit.c
index b21335e..786bb7a 100644
--- a/commit.c
+++ b/commit.c
@@ -6,6 +6,7 @@
 #include "diff.h"
 #include "revision.h"
 #include "notes.h"
+#include "sorted-array.h"
 
 int save_commit_buffer = 1;
 
@@ -89,33 +90,32 @@ static unsigned long parse_commit_date(const char *buf, const char *tail)
 	return strtoul(dateptr, NULL, 10);
 }
 
-static struct commit_graft **commit_graft;
-static int commit_graft_alloc, commit_graft_nr;
-
-static int commit_graft_pos(const unsigned char *sha1)
+static int commit_graft_cmp(const unsigned char *ref_sha1, struct commit_graft **elem)
 {
-	int lo, hi;
-	lo = 0;
-	hi = commit_graft_nr;
-	while (lo < hi) {
-		int mi = (lo + hi) / 2;
-		struct commit_graft *graft = commit_graft[mi];
-		int cmp = hashcmp(sha1, graft->sha1);
-		if (!cmp)
-			return mi;
-		if (cmp < 0)
-			hi = mi;
-		else
-			lo = mi + 1;
-	}
-	return -lo - 1;
+	return hashcmp(ref_sha1, (*elem)->sha1);
 }
+declare_sorted_array(static, struct commit_graft *, commit_graft);
+declare_sorted_array_search_check(static, struct commit_graft *, commit_graft_pos,
+				  const unsigned char *,
+				  commit_graft, commit_graft_cmp);
 
+// FIXME: do we want to/can we remove INITTYPE from gen_binsearch ?
+static int commit_graft_cmp2(struct commit_graft *ref_graft, struct commit_graft **elem)
+{
+	return commit_graft_cmp(ref_graft->sha1, elem);
+}
+static void commit_graft_init(struct commit_graft **elem, struct commit_graft *ref_graft)
+{
+	*elem = ref_graft;
+}
+declare_sorted_array_insertonly_check(static, struct commit_graft *, register_commit_graft0,
+				      struct commit_graft *,
+				      commit_graft, commit_graft_cmp2, commit_graft_init);
 int register_commit_graft(struct commit_graft *graft, int ignore_dups)
 {
-	int pos = commit_graft_pos(graft->sha1);
+	int pos = register_commit_graft0(graft);
 
-	if (0 <= pos) {
+	if (pos >= 0) {
 		if (ignore_dups)
 			free(graft);
 		else {
@@ -124,19 +124,6 @@ int register_commit_graft(struct commit_graft *graft, int ignore_dups)
 		}
 		return 1;
 	}
-	pos = -pos - 1;
-	if (commit_graft_alloc <= ++commit_graft_nr) {
-		commit_graft_alloc = alloc_nr(commit_graft_alloc);
-		commit_graft = xrealloc(commit_graft,
-					sizeof(*commit_graft) *
-					commit_graft_alloc);
-	}
-	if (pos < commit_graft_nr)
-		memmove(commit_graft + pos + 1,
-			commit_graft + pos,
-			(commit_graft_nr - pos - 1) *
-			sizeof(*commit_graft));
-	commit_graft[pos] = graft;
 	return 0;
 }
 
-- 
1.7.2.3

^ permalink raw reply related

* [PATCH 1/6] Introduce sorted-array binary-search function.
From: Yann Dirson @ 2010-12-08 22:51 UTC (permalink / raw)
  To: git; +Cc: Yann Dirson
In-Reply-To: <1291848695-24601-1-git-send-email-ydirson@altern.org>

We use a cpp-based template mechanism to declare the array and its
management data, as well as a search function.
Thanks to Jonathan Nieder for this design idea.

Signed-off-by: Yann Dirson <ydirson@altern.org>
---
 Documentation/technical/api-sorted-array.txt |  132 ++++++++++++++++++++++++++
 Makefile                                     |    1 +
 sorted-array.h                               |  128 +++++++++++++++++++++++++
 3 files changed, 261 insertions(+), 0 deletions(-)
 create mode 100644 Documentation/technical/api-sorted-array.txt
 create mode 100644 sorted-array.h

diff --git a/Documentation/technical/api-sorted-array.txt b/Documentation/technical/api-sorted-array.txt
new file mode 100644
index 0000000..b1238ad
--- /dev/null
+++ b/Documentation/technical/api-sorted-array.txt
@@ -0,0 +1,132 @@
+sorted-array API
+================
+
+The sorted-array API is meant to provide efficient binary-search
+functions into a C array of elements of arbitrary type, and insert
+functions that maintain ordering.
+
+It is meant for data structures where lookup time is much more
+important than insertion type: while lookup has o(log(n)) time
+complexity, insertion has o(n) and involves many copies.
+
+API overview
+------------
+
+The API allow to declare all variables and function as static or not,
+through the first argument to all macros, which can be `static` or
+empty.
+
+It is based on the idea of providing custom functions, which will then
+be used by generic algorithms:
+* one for comparing a search term with an array item
+* one for initializing a new array item from a search term after insertion
+
+A set of convenience wrapper macros are provided, to define a readable
+API for inserting and sorting.
+
+Note that the type of the search term can be different from the type
+of array elements (which can be more expensive to create).
+
+API reference
+-------------
+
+The macros can be categorized as follows:
+
+* the one used to define a sorted array, and its management variable
+  holding currently-allocated number of elements and number of
+  elements effectively used.  The name of those (int) management
+  variables are crafted by using the `LISTNAME` and appending
+  respectively `_alloc` and `_nr`.
++
+----
+declare_sorted_array(MAYBESTATIC,ELEMTYPE,LISTNAME)
+----
++
+eg:
++
+----
+declare_sorted_array(static, struct diff_rename_dst, rename_dst);
+----
+
+* those defining ready-for-use search and insert functions.  They
+  exist in several flavours, distinguished by their suffix, which
+  refer to different return-type semantics.
++
+----
+declare_sorted_array_search_*(MAYBESTATIC,ELEMTYPE,FUNCNAME,INITTYPE,LISTNAME,CMP)
+declare_sorted_array_insert_*(MAYBESTATIC,ELEMTYPE,FUNCNAME,INITTYPE,GENSEARCH,LISTNAME,CMP,INIT)
+----
++
+They all work by defining behind the scene a (static) generic search or insert
+function named with `_gen_` prepended to `FUNCNAME`.  Such generic functions
+may be useful to know about if you need to define an insert function with
+the exact same parameters.
++
+All functions of a given type (search or insert) take the same kind of
+arguments:
+
+`MAYBESTATIC`::
+	the ubiquitous `static`or empty placeholder
+`ELEMTYPE`::
+	type of element to be stored in the array
+`FUNCNAME`::
+	name of the function to be defined
+`INITTYPE`::
+	type of search term / initializer passed as argument to the
+	generated function
+`LISTNAME`::
+	name of the array in which the search takes place, usually declared
+	through `declare_sorted_array()`
+`CMP`::
+	comparison function taking an INITTYPE argument and a
+	pointer to an ELEMTYPE argument, and returning an int with
+	the same meaning as `strcmp()`.
+`GENSEARCH`::
+	(insert only) generic search function generated by
+	`declare_gen_binsearch()`
+`INIT`::
+	(insert only) element-initializer function taking as arguments
+	pointer to the ELEMTYPE to be initialized, and an INITTYPE argument
+	to take information from
+
+
+Suffix meanings are as follows:
+
+`check`::
+
+	Returns the position of the element if found pre-existing in
+	the list, or if not found, (-pos - 1) where pos is where the
+	element would have been (for search funcs) or has been (for
+	insert funcs) inserted.
+
+`checkbool`::
+
+	Returns an int, just telling whether the searched element was
+	pre-existing in the list (1) or not (0).
+
+`elem`::
+
+	Returns NULL if the search term was not found (for search
+	funcs), or a pointer to the element found or newly inserted.
+
+* those defining even-more-ready-for-use insert functions, which do
+  not need to define the generic search function at all.  Those macro
+  names are the same as the forms with an `GENSEARCH` argument, but
+  with a name ending in `_insertonly_*`, and without that `GENSEARCH`
+  argument.  The generic (static) search functions are named as
+  `_gensearch` prepended to the `FUNCNAME` argument.
+
+* those defining the generic algorithms
++
+They rarely need to be used directly, they are usually expanded
+transparently from the `declare_sorted_array_*` macros.
++
+----
+declare_gen_binsearch(MAYBESTATIC,ELEMTYPE,FUNCNAME,INITTYPE)
+declare_gen_sorted_insert(MAYBESTATIC,ELEMTYPE,FUNCNAME,SEARCHFUNC,INITTYPE)
+----
+
+* those defining the individual wrappers
++
+They rarely need to be used directly, they are usually expanded
+transparently from the `declare_sorted_array_*` macros.
diff --git a/Makefile b/Makefile
index 7eb948d..522261e 100644
--- a/Makefile
+++ b/Makefile
@@ -544,6 +544,7 @@ LIB_H += run-command.h
 LIB_H += sha1-lookup.h
 LIB_H += sideband.h
 LIB_H += sigchain.h
+LIB_H += sorted-array.h
 LIB_H += strbuf.h
 LIB_H += string-list.h
 LIB_H += submodule.h
diff --git a/sorted-array.h b/sorted-array.h
new file mode 100644
index 0000000..added0e
--- /dev/null
+++ b/sorted-array.h
@@ -0,0 +1,128 @@
+#ifndef SORTED_ARRAY_H_
+#define SORTED_ARRAY_H_
+
+/*
+ * Sorted-array management.
+ * See Documentation/technical/api-sorted-array.txt
+ */
+
+#define declare_sorted_array(MAYBESTATIC,ELEMTYPE,LIST)			\
+MAYBESTATIC ELEMTYPE *LIST;						\
+MAYBESTATIC int LIST##_nr, LIST##_alloc;
+
+#define declare_gen_binsearch(MAYBESTATIC,ELEMTYPE,FUNCNAME,INITTYPE)	\
+MAYBESTATIC int FUNCNAME(						\
+	ELEMTYPE *list, int list_nr,					\
+	int(*cmp_func)(INITTYPE ref, ELEMTYPE *elem),			\
+	INITTYPE data)							\
+{									\
+	int lo, hi;							\
+									\
+	lo = 0;								\
+	hi = list_nr;							\
+	while (hi > lo) {						\
+		int mid = (hi + lo) >> 1;				\
+		int cmp = cmp_func(data, list + mid);			\
+		if (!cmp)						\
+			return mid;					\
+		if (cmp < 0)						\
+			hi = mid;					\
+		else							\
+			lo = mid + 1;					\
+	}								\
+	return -lo - 1;							\
+}
+
+#define declare_gen_sorted_insert(MAYBESTATIC,ELEMTYPE,FUNCNAME,SEARCHFUNC,INITTYPE) \
+MAYBESTATIC int FUNCNAME(						\
+	ELEMTYPE **list_p, int *list_nr_p, int *list_alloc_p,		\
+	int(*cmp_func)(INITTYPE ref, ELEMTYPE *elem),			\
+	void(*init_func)(ELEMTYPE *elem, INITTYPE init),		\
+	INITTYPE data)							\
+{									\
+	int pos = SEARCHFUNC(*list_p, *list_nr_p, cmp_func, data);	\
+	if (pos >= 0) 							\
+		return pos;						\
+	/* not found */							\
+	pos = -pos - 1;							\
+	/* insert to make it at "pos" */				\
+	if (*list_alloc_p <= *list_nr_p) {				\
+		(*list_alloc_p) = alloc_nr((*list_alloc_p));		\
+		*list_p = xrealloc(*list_p,				\
+				   (*list_alloc_p) * sizeof(**list_p)); \
+	}								\
+	(*list_nr_p)++;							\
+	if (pos < *list_nr_p)						\
+		memmove(*list_p + pos + 1, *list_p + pos,		\
+			(*list_nr_p - pos - 1) * sizeof(**list_p));	\
+	init_func(&(*list_p)[pos], data);				\
+	return -pos - 1;						\
+}
+
+#define _declare_sorted_array_search_check(MAYBESTATIC,FUNCNAME,INITTYPE,GENSEARCH,LIST,CMP) \
+MAYBESTATIC int FUNCNAME(INITTYPE data)					\
+{									\
+	return GENSEARCH(LIST, LIST##_nr, CMP, data);			\
+}
+#define declare_sorted_array_search_check(MAYBESTATIC,ELEMTYPE,FUNCNAME,INITTYPE,LIST,CMP) \
+  declare_gen_binsearch(MAYBESTATIC,ELEMTYPE,_gen_##FUNCNAME,INITTYPE); \
+  _declare_sorted_array_search_check(MAYBESTATIC,FUNCNAME,INITTYPE,_gen_##FUNCNAME,LIST,CMP);
+
+#define _declare_sorted_array_insert_check(MAYBESTATIC,FUNCNAME,INITTYPE,GENINSERT,LIST,CMP,INIT) \
+MAYBESTATIC int FUNCNAME(INITTYPE data)					\
+{									\
+	return GENINSERT(&LIST, &LIST##_nr, &LIST##_alloc,		\
+			 CMP, INIT, data);				\
+}
+#define declare_sorted_array_insert_check(MAYBESTATIC,ELEMTYPE,FUNCNAME,INITTYPE,GENSEARCH,LIST,CMP,INIT) \
+  declare_gen_sorted_insert(static,ELEMTYPE,_gen_##FUNCNAME,GENSEARCH,INITTYPE); \
+  _declare_sorted_array_insert_check(MAYBESTATIC,FUNCNAME,INITTYPE,_gen_##FUNCNAME,LIST,CMP,INIT);
+#define declare_sorted_array_insertonly_check(MAYBESTATIC,ELEMTYPE,FUNCNAME,INITTYPE,LIST,CMP,INIT) \
+  declare_gen_binsearch(static,ELEMTYPE,_gensearch_##FUNCNAME,INITTYPE); \
+  declare_sorted_array_insert_check(MAYBESTATIC,ELEMTYPE,FUNCNAME,INITTYPE,_gensearch_##FUNCNAME,LIST,CMP,INIT);
+
+#define _declare_sorted_array_insert_checkbool(MAYBESTATIC,FUNCNAME,INITTYPE,GENINSERT,LIST,CMP,INIT) \
+MAYBESTATIC int FUNCNAME(INITTYPE data)					\
+{									\
+	int idx = GENINSERT(&LIST, &LIST##_nr, &LIST##_alloc,		\
+			    CMP, INIT, data);				\
+	if (idx < 0)							\
+		return 0;						\
+	return 1;							\
+}
+#define declare_sorted_array_insert_checkbool(MAYBESTATIC,ELEMTYPE,FUNCNAME,INITTYPE,GENSEARCH,LIST,CMP,INIT) \
+  declare_gen_sorted_insert(static,ELEMTYPE,_gen_##FUNCNAME,GENSEARCH,INITTYPE); \
+  _declare_sorted_array_insert_checkbool(MAYBESTATIC,FUNCNAME,INITTYPE,_gen_##FUNCNAME,LIST,CMP,INIT);
+#define declare_sorted_array_insertonly_checkbool(MAYBESTATIC,ELEMTYPE,FUNCNAME,INITTYPE,LIST,CMP,INIT) \
+  declare_gen_binsearch(static,ELEMTYPE,_gensearch_##FUNCNAME,INITTYPE); \
+  declare_sorted_array_insert_checkbool(MAYBESTATIC,ELEMTYPE,FUNCNAME,INITTYPE,_gensearch_##FUNCNAME,LIST,CMP,INIT);
+
+#define _declare_sorted_array_search_elem(MAYBESTATIC,ELEMTYPE,FUNCNAME,INITTYPE,GENSEARCH,LIST,CMP) \
+MAYBESTATIC ELEMTYPE *FUNCNAME(INITTYPE data)				\
+{									\
+	int idx = GENSEARCH(LIST, LIST##_nr, CMP, data);		\
+	if (idx < 0)							\
+		return NULL;						\
+	return &(LIST[idx]);						\
+}
+#define declare_sorted_array_search_elem(MAYBESTATIC,ELEMTYPE,FUNCNAME,INITTYPE,LIST,CMP) \
+  declare_gen_binsearch(static,ELEMTYPE,_gen_##FUNCNAME,INITTYPE); \
+  _declare_sorted_array_search_elem(MAYBESTATIC,ELEMTYPE,FUNCNAME,INITTYPE,_gen_##FUNCNAME,LIST,CMP);
+
+#define _declare_sorted_array_insert_elem(MAYBESTATIC,ELEMTYPE,FUNCNAME,INITTYPE,GENINSERT,LIST,CMP,INIT) \
+MAYBESTATIC ELEMTYPE *FUNCNAME(INITTYPE data)				\
+{									\
+	int idx = GENINSERT(&LIST, &LIST##_nr, &LIST##_alloc,		\
+			    CMP, INIT, data);				\
+	if (idx < 0)							\
+		idx = -idx - 1;						\
+	return &(LIST[idx]);						\
+}
+#define declare_sorted_array_insert_elem(MAYBESTATIC,ELEMTYPE,FUNCNAME,INITTYPE,GENSEARCH,LIST,CMP,INIT) \
+  declare_gen_sorted_insert(static,ELEMTYPE,_gen_##FUNCNAME,GENSEARCH,INITTYPE); \
+  _declare_sorted_array_insert_elem(MAYBESTATIC,ELEMTYPE,FUNCNAME,INITTYPE,_gen_##FUNCNAME,LIST,CMP,INIT);
+#define declare_sorted_array_insertonly_elem(MAYBESTATIC,ELEMTYPE,FUNCNAME,INITTYPE,LIST,CMP,INIT) \
+  declare_gen_binsearch(static,ELEMTYPE,_gensearch_##FUNCNAME,INITTYPE); \
+  declare_sorted_array_insert_elem(MAYBESTATIC,ELEMTYPE,FUNCNAME,INITTYPE,_gensearch_##FUNCNAME,LIST,CMP,INIT);
+
+#endif
-- 
1.7.2.3

^ permalink raw reply related

* [PATCH v6] generalizing sorted-array handling
From: Yann Dirson @ 2010-12-08 22:51 UTC (permalink / raw)
  To: git

I hope the improvements to the usage syntax in this version would help
to get more feedback.  I don't plan to do much more structural work on
this, unless reviewers complain.  I want to get my focus back to
bulk-rename/builk-rm patches, which will make heavy use of this API.

Changes from v5:

* moved doc to Documentation/api-sorted-array.txt as suggested by
  Jonathan Nieder, made it a bit more comprehensive as well.

* changed API with:
  * renamed low-level wrapper-decl macros with a leading underscore
  * provide high-level wrapper-decl macros for everyday use, which
    declare the required generic funcs for use (as static funcs)

Those high-level macros make the entry points more numerousas
previously noted, but we gain much in usage clarity, as well as
consistent API (no more argument differences between macros of a
single level)

By using those macros we lose the control we had on all the
intermediate funcs, but that should not be much of a problem.


Notes on current API:

* The macro names are a bit heavy-weight.  Better ideas welcome.

* could gain a dealloc API, to minimize the explicit use of the _nr
  and _alloc vars


The following binary-search occurences were not converted:

* read-cache.c::index_name_pos has widely-used API with 2 low-coupled
  cmp/init params: sorted-array could be generalized at the cost of
  using stdarg, but is it worth it ?

* pack-revindex.c::find_pack_revindex is a bit special and needs more
  thought

* cache-tree.c::subtree_pos and sha1_file::find_pack_entry_one too

* sha1_lookup.c stuff probably too special

^ permalink raw reply

* Re: [PATCH 2/2] get_sha1: support ref^{/regex} syntax
From: Junio C Hamano @ 2010-12-08 22:50 UTC (permalink / raw)
  To: Nguyễn Thái Ngọc Duy
  Cc: git, Kevin Ballard, Yann Dirson, Jeff King, Jakub Narebski
In-Reply-To: <1291820319-12455-3-git-send-email-pclouds@gmail.com>

Nguyễn Thái Ngọc Duy <pclouds@gmail.com> writes:

> diff --git a/sha1_name.c b/sha1_name.c
> index f4ccdc5..00e52b0 100644
> --- a/sha1_name.c
> +++ b/sha1_name.c
> @@ -562,6 +563,11 @@ static int peel_onion(const char *name, int len, unsigned char *sha1)
>  		expected_type = OBJ_BLOB;
>  	else if (sp[0] == '}')
>  		expected_type = OBJ_NONE;
> +	else if (sp[0] == '/') {
> +		if (sp[1] == '}')
> +			return -1;

Why?  $commit^{/} may be a no-op but I do not see a strong reason to
waste extra two lines to forbid it.

> @@ -584,11 +590,23 @@ static int peel_onion(const char *name, int len, unsigned char *sha1)
>  		 * barf.
>  		 */
>  		o = peel_to_type(name, len, o, expected_type);
> -		if (o) {
> -			hashcpy(sha1, o->sha1);
> -			return 0;
> +		if (!o)
> +			return -1;

I can see you are trying to reduce nesting of

        if (o) {
		do true thing
                return 0
	}
        return -1;

but then we should apply the same to outer "if (!expected_type) ... else",
too, to unnest the "else" clause by returning from the true branch of that
"if".

^ permalink raw reply

* Re: [PATCH v2.1 3/4] describe: Store commit_names in a hash table by commit SHA1
From: Junio C Hamano @ 2010-12-08 22:50 UTC (permalink / raw)
  To: Anders Kaseorg
  Cc: Jonathan Nieder, git, SZEDER Gábor, Kirill Smelkov,
	Thomas Rast
In-Reply-To: <alpine.DEB.2.02.1012081319320.23348@dr-wily.mit.edu>

Anders Kaseorg <andersk@ksplice.com> writes:

> @@ -44,6 +47,19 @@ static const char *prio_names[] = {
>  	"head", "lightweight", "annotated",
>  };
>  
> +static inline unsigned int hash_sha1(const unsigned char *sha1)
> +{
> +	return *(unsigned int *)sha1;
> +}

Do we know that all the archs we will be compiled on will be happy with
this potentially unaligned access?  hash_filespec() in diffcore-rename.c
is written in a way to avoid such an issue, and I would feel safer to see
this do the same.

^ permalink raw reply

* Re: [PATCH v2 4/4] describe: Delay looking up commits until searching for an inexact match
From: Junio C Hamano @ 2010-12-08 22:50 UTC (permalink / raw)
  To: Anders Kaseorg
  Cc: Jonathan Nieder, git, SZEDER Gábor, Kirill Smelkov,
	Thomas Rast
In-Reply-To: <alpine.DEB.2.02.1012072344000.23348@dr-wily.mit.edu>

Anders Kaseorg <andersk@ksplice.com> writes:

> Now that struct commit.util is not used until after we’ve checked that
> the argument doesn’t exactly match a tag, we can wait until then to
> look up the commits for each tag.
>
> This avoids a lot of I/O on --exact-match queries in repositories with
> many tags.  For example, ‘git describe --exact-match HEAD’ becomes
> about 12 times faster on a cold cache (3.2s instead of 39s) in a
> linux-2.6 repository with 2000 packed tags.  That’s a huge win for the
> interactivity of the __git_ps1 shell prompt helper when on a detached
> HEAD.

You seem to have gone in a slightly different direction with this reroll.
I am not sure if use of hash_table in this code would actually improve
anything (aside from the general readability and "reusing code from a good
infrastructure is a good thing" principle), though, no matter how many
tags you have in your repository.  In the code from the earlier round,
lookup_commit_reference_gently call in the fallback codepath to populate
commit->util used the *obj_hash[] to quickly look up the commits with the
same object name already.

> @@ -60,6 +61,15 @@ static inline struct commit_name *find_commit_name(const unsigned char *peeled)
>  	return n;
>  }
>  
> +static int set_util(void *vn)
> +{
> +	struct commit_name *n = vn;
> +	struct commit *c = lookup_commit_reference_gently(n->peeled, 1);
> +	if (c)
> +		c->util = n;
> +	return 0;
> +}

I don't know how the above would work in the face of hash collisions.

This is a callback for for_each_hash(), which visits each populated entry
in the underlying hash table.  The semantics of the hash table hash.c
gives you is "here is a flat hash table.  We insert only to an empty
field, and otherwise we will tell you where your new element would have
hashed into, so that you can implement linear overflow or chained buckets
yourself on top of this", and you chose to implement bucket chaining in
add_to_known_names(), so don't you need to walk the chain here for commits
that share the same first four bytes in their object names?

^ permalink raw reply

* Re: how to have real (existing) submodules?
From: Seth Robertson @ 2010-12-08 22:25 UTC (permalink / raw)
  To: Oliver Kullmann; +Cc: git
In-Reply-To: <20101208205846.GW29789@cs-wsok.swansea.ac.uk>


In message <20101208205846.GW29789@cs-wsok.swansea.ac.uk>, Oliver Kullmann writ
es:

    I thought that "git submodule" would solve the problem, but now I
    realised that these submodules are not "real", but they only
    contain a bit of meta-data (this should really be said directly in
    the documentation).

    So my hope, that I can have one super-repo, where I say, e.g.,
    "git submodule foreach pull", get the full super-repo, copy it on
    a memory stick, and then by pulling from that copy I get
    everything into another super-repo, from which I distribute the
    sub-repos, seems not so easily realisable with git?

gitslave may work for you better than git-submodules in this specific
use case.  http://gitslave.sf.net

In your example, you would create an organizational super-project git
module which is primarily a container for the .gitslave file which
tells the system how to access the various git repos and their on-disk
path names.

Given your diverse repo locations, it sounds like you will not be
using the feature which allows the pathnames of the slave repos to be
relative based on the URL to the super-repo (though you could have a
mixture of relative and absolute URLs if that would help your
functionality).

You would then run `gits pull` to issue a `git pull` against every
slave repo, and likewise `gits push` or `gits push home` or whatever.
(remotes would best work if your gitslave system has relative URLs).
While the super-project cannot be bare, the slave-repos could be bare
if that would help your data transfer functionality.

If certain slave repos would not be accessible in all locations, there
are options to bypass the errors you will get attempting to contact
the unreachable repos.

If you have any questions, please let me know (here, private email, or
on #git).

					-Seth Robertson

^ permalink raw reply

* Re: cherry-pick / pre-commit hook?
From: Jonathan Nieder @ 2010-12-08 22:05 UTC (permalink / raw)
  To: Dave Abrahams; +Cc: git
In-Reply-To: <m2oc8wt0xc.wl%dave@boostpro.com>

Dave Abrahams wrote:

> You're going to love this: I had sent a pull request upstream and the
> maintainer of the project rejected my changes because I didn't follow
> some formatting convention he didn't tell me about ;-).  So I set up a
> commit hook that would prevent me from making the same mistake again,
> and cherry-picked the changes one-by-one.

Funny.  Maybe "cherry-pick --no-commit" followed by ordinary commit
would be appropriate?  That way, when the checks fail, you are in a
position to clean them up.

If the conventions were whitespace related, "git rebase --whitespace=fix"
might be even more useful.

Just for kicks, here is the cherry-pick --verify for picky
cherry-pickers.

-- 8< --
Subject: cherry-pick/revert: learn --verify to run pre-commit and commit-msg hooks

The main purpose of the pre-commit and commit-msg hooks is to avoid
introducing regressions in whitespace style, encoding, and so forth;
and it would make cherry-picking unnecessarily difficult, without
preventing regressions, to unconditionally apply the same standards to
existing code.  For this reason, in v0.99.6~51 (2005-08-29), git
learned to skip the usual hooks when cherry-picking or reverting an
existing commit.

But sometimes the checks are wanted anyway.  For example, with this
patch applied, you can safely fetch some new contributor's code:

	$ git cherry-pick -s --verify HEAD..FETCH_HEAD

while allowing the pre-commit and commit-msg hooks to run their usual
checks so the result can error out if the patches are not clean.

Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
---
Untested.  Please feel free to add some documentation and tests and
submit it for real if this looks like a good idea. :)

 builtin/revert.c |    6 ++++--
 1 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/builtin/revert.c b/builtin/revert.c
index bb6e9e8..511b2ea 100644
--- a/builtin/revert.c
+++ b/builtin/revert.c
@@ -36,7 +36,7 @@ static const char * const cherry_pick_usage[] = {
 	NULL
 };
 
-static int edit, no_replay, no_commit, mainline, signoff, allow_ff;
+static int edit, no_replay, no_commit, verify, mainline, signoff, allow_ff;
 static enum { REVERT, CHERRY_PICK } action;
 static struct commit *commit;
 static int commit_argc;
@@ -67,6 +67,7 @@ static void parse_args(int argc, const char **argv)
 		OPT_INTEGER('m', "mainline", &mainline, "parent number"),
 		OPT_RERERE_AUTOUPDATE(&allow_rerere_auto),
 		OPT_STRING(0, "strategy", &strategy, "strategy", "merge strategy"),
+		OPT_BOOLEAN(0, "verify", &verify, "let hooks intervene before commiting"),
 		OPT_END(),
 		OPT_END(),
 		OPT_END(),
@@ -375,7 +376,8 @@ static int run_git_commit(const char *defmsg)
 	int i = 0;
 
 	args[i++] = "commit";
-	args[i++] = "-n";
+	if (!verify)
+		args[i++] = "-n";
 	if (signoff)
 		args[i++] = "-s";
 	if (!edit) {
-- 
1.7.2.4

^ permalink raw reply related

* Re: Vendor branches workflow
From: Neal Kreitzinger @ 2010-12-08 21:54 UTC (permalink / raw)
  To: git
In-Reply-To: <AANLkTi=s9p3RycRCrocHEzfc4L-pnU6S9xCKfEL7TP=i@mail.gmail.com>

"Leonid Podolny" <leonidp.lists@gmail.com> wrote in message 
news:AANLkTi=s9p3RycRCrocHEzfc4L-pnU6S9xCKfEL7TP=i@mail.gmail.com...
> Hi, list,
> I would like an advice on organizing a vendor branch workflow, to
> minimize the risk of it biting me in the future.
> In our project, we have two upstreams, which are rather massively
> patched. One of the upstreams is an SF svn repository, the other
> arrives in form of tgz's with sources. Now git is tracking the patched
> version, and I want to add a vendor branch to simplify future vendor
> drops.
> Out of the SVN upstream, we use only specific directories.
> So, two questions:
> - How do I deal with unneeded directories? Do I filter them out before
> commiting to the vendor branch or while merging the vendor branch into
> the master?
> - Do you think it would be a good idea to keep .svn directories around
> at the vendor branch? (Kind of connected to the first question,
> because if I keep the .svn's, I will also have to keep the unneeded
> dirs).

The git-rm manpage explains a methodology for vendor branches.  Maybe you've 
already read it...

v/r,
Neal 

^ 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