Re: [ANNOUNCE] Git v1.8.5-rc1

2013-11-07 Thread Christian Couder
On Thu, Nov 7, 2013 at 12:57 AM, Junio C Hamano gits...@pobox.com wrote:

  * git replace helper no longer allows an object to be replaced with
another object of a different type to avoid confusion (you can
still manually craft such replacement using git update-ref, as an
escape hatch).

Maybe it would be more helpful to say you can still do that using the
--force option instead of pointing people to git update-ref.

Thanks,
Christian.
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v3] push: Enhance unspecified push default warning

2013-11-07 Thread Matthieu Moy
Jonathan Nieder jrnie...@gmail.com writes:

   When push.default is set to 'matching', git will push local branches
   to remote branches that already exist with the same (matching) name.

Yes, that's better than the original patch (and remains two lines).

 +   In Git 2.0 the new push.default of 'simple' will push only the 
 current\n
 +   branch to the same remote branch used by git pull.   A push will\n
 +   only succeed if the remote and local branches have the same name.\n

 while you can see that it is not telling a lie if you read it twice,
 will only succeed if feels somewhat roundabout.

 ... push only the current branch back to the branch of the
 same name, but only if 'git pull' is set to pull from that
 branch. Otherwise the push will fail.

 might be an improvement, but I dunno.

 I do not see much difference actually. I tend to prefer the original
 version: to me the expected behavior is to make push and pull
 essentially symetrical, and the fact that it fails if the branch is
 named differently is a safety feature comming on top of that.

 Perhaps:

   In Git 2.0 (or now, if push.default is set to 'simple'), git will behave
   more conservatively by pushing only the current branch to the 
 corresponding
   remote branch used by git pull, and only if the remote and local 
 branches
   have the same name.

I prefered the original, as it had two sentences. Reading only the first
one gave the important information.

   In Git 2.0, git will default to a more conservative 'simple' behavior
   that only pushes the current branch.

That's an option too, but I think mentionning git pull was a good
idea.

-- 
Matthieu Moy
http://www-verimag.imag.fr/~moy/
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v3 2/2] Rename suffixcmp() to has_suffix() and invert its result

2013-11-07 Thread Christian Couder
On Thu, Nov 7, 2013 at 1:12 AM, Junio C Hamano gits...@pobox.com wrote:
 Jonathan Nieder jrnie...@gmail.com writes:

 The old name followed the pattern anything-cmp(), which suggests
 a general comparison function suitable for e.g. sorting objects.
 But this was not the case for suffixcmp().

 It's not clear to me that prefixcmp() is usable for sorting objects,
 either.  Shouldn't it get the same treatment?

 Sounds like a plan for a good follow-up series.

Ok, I will have a look.

 If some day we invent a type for 4-byte-aligned object names, it might
 make sense to do something similar to hashcmp, distinguishing between
 hashcmp for use where ordering is important and something like hash_eq
 when checking for equality (since I suspect the latter can be made
 faster).

 Interesting.

Yeah, but I will pass on this one.

Thanks,
Christian.
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v4 00/14] New hash table implementation

2013-11-07 Thread Karsten Blees
Also here:
https://github.com/kblees/git/commits/kb/hashmap-v4

Sorry for the delay, but the promised static use-after-free analysis [1] turned 
out to be much more involved than I had anticipated.

The Good News is that the static analysis independently found the four 
use-after-free issues that we already knew about (two fixed in my initial patch 
10, and two more found by Thomas' valgrind tests). These are all fixed in this 
round.

Valgrind tests ran over night and only reported a single unrelated problem 
(glibc strlen() working in 4-byte chunks and thus exceeding the malloced space 
in builtin/fetch.c:462).

The Bad News is that I'm a bit clueless regarding unpack-trees.c, so I'd 
welcome if someone more familiar with that part of git could have a look (see 
analysis below).


The first 11 patches in this version are exactly as currently in pu, just 
rebased to next. The problematic memory-leaks patch is at the very end, so we 
could merge the rest and cook this one a bit longer...

Changes since v3:
- included Jens Lehmann's submodule use-after-free fix [2] (#01)
- added minor fix for 'git update-index --verbose' output (#12)
- added minor cleanup patch for builtin/update-index.c (#13)
- moved the problematic 'fix memory leaks' patch to the end (#14)
- included fix for first valgrind breakage [3] (already in pu) (#14)
- added fix for second valgrind breakage reported in [4] (#14)

[1] http://article.gmane.org/gmane.comp.version-control.git/236467
[2] http://article.gmane.org/gmane.comp.version-control.git/236370
[3] http://article.gmane.org/gmane.comp.version-control.git/236468
[4] http://article.gmane.org/gmane.comp.version-control.git/236869

Jens Lehmann (1):
  submodule: don't access the .gitmodules cache entry after removing it

Karsten Blees (13):
  add a hashtable implementation that supports O(1) removal
  buitin/describe.c: use new hash map implementation
  diffcore-rename.c: move code around to prepare for the next patch
  diffcore-rename.c: simplify finding exact renames
  diffcore-rename.c: use new hash map implementation
  name-hash.c: use new hash map implementation for directories
  name-hash.c: remove unreferenced directory entries
  name-hash.c: use new hash map implementation for cache entries
  name-hash.c: remove cache entries instead of marking them CE_UNHASHED
  remove old hash.[ch] implementation
  fix 'git update-index --verbose --again' output
  builtin/update-index.c: cleanup update_one
  read-cache.c: fix memory leaks caused by removed cache entries

 Documentation/technical/api-hash.txt|  52 ---
 Documentation/technical/api-hashmap.txt | 237 +
 Makefile|   5 +-
 builtin/describe.c  |  53 +++
 builtin/rm.c|   2 +-
 builtin/update-index.c  |  39 +++--
 cache.h |  18 +--
 diffcore-rename.c   | 185 ---
 hash.c  | 110 --
 hash.h  |  50 ---
 hashmap.c   | 212 ++
 hashmap.h   |  72 +
 name-hash.c | 156 +++
 read-cache.c|  10 +-
 resolve-undo.c  |   7 +-
 submodule.c |  25 +---
 t/t0011-hashmap.sh  | 236 +
 test-hashmap.c  | 256 
 unpack-trees.c  |   3 +-
 19 files changed, 1199 insertions(+), 529 deletions(-)
 delete mode 100644 Documentation/technical/api-hash.txt
 create mode 100644 Documentation/technical/api-hashmap.txt
 delete mode 100644 hash.c
 delete mode 100644 hash.h
 create mode 100644 hashmap.c
 create mode 100644 hashmap.h
 create mode 100755 t/t0011-hashmap.sh
 create mode 100644 test-hashmap.c

===

Potential use-after-free problems in unpack-trees.c:


Basic analysis of unpack-trees.c is that most callers go through add_entry or 
merged_entry, which both add a copy of the cache_entry to a separate 
index_state (unpack_trees_options.result). This may replace and free entries in 
unpack_trees_options.result, which is (mostly) ok because 
unpack_trees_options.result is (mostly) not used otherwise. Adding copies to a 
separate index is completely safe, so we don't even have to look at most of the 
other functions in unpack-trees.c.

The two call hierarchies that I'm worried about are as follows:

1.  unpack_callback may pass a cache_entry from unpack_trees_options.src_index
to unpack_nondirectories (as src[0]), which _may_ add it to
unpack_trees_options.result without making a copy.
1a. adding a cache_entry from src_index to result without making a copy
destroys hashtable chaining in 

[PATCH v4 01/14] submodule: don't access the .gitmodules cache entry after removing it

2013-11-07 Thread Karsten Blees
Commit 5fee995244e introduced the stage_updated_gitmodules() function to
add submodule configuration updates to the index. It assumed that even
after calling remove_cache_entry_at() the same cache entry would still be
valid. This was true in the old days, as cache entries could never be
freed, but that is not so sure in the present as there is ongoing work to
free removed cache entries, which makes this code segfault.

Fix that by calling add_file_to_cache() instead of open coding it. Also
remove the could not find .gitmodules in index warning, as that won't
happen in regular use cases (and by then just silently adding it to the
index we do the right thing).

Thanks-to: Karsten Blees karsten.bl...@gmail.com
Signed-off-by: Jens Lehmann jens.lehm...@web.de
Signed-off-by: Junio C Hamano gits...@pobox.com
---
 submodule.c | 25 +
 1 file changed, 1 insertion(+), 24 deletions(-)

diff --git a/submodule.c b/submodule.c
index 1905d75..e388487 100644
--- a/submodule.c
+++ b/submodule.c
@@ -116,30 +116,7 @@ int remove_path_from_gitmodules(const char *path)
 
 void stage_updated_gitmodules(void)
 {
-   struct strbuf buf = STRBUF_INIT;
-   struct stat st;
-   int pos;
-   struct cache_entry *ce;
-   int namelen = strlen(.gitmodules);
-
-   pos = cache_name_pos(.gitmodules, namelen);
-   if (pos  0) {
-   warning(_(could not find .gitmodules in index));
-   return;
-   }
-   ce = active_cache[pos];
-   ce-ce_flags = namelen;
-   if (strbuf_read_file(buf, .gitmodules, 0)  0)
-   die(_(reading updated .gitmodules failed));
-   if (lstat(.gitmodules, st)  0)
-   die_errno(_(unable to stat updated .gitmodules));
-   fill_stat_cache_info(ce, st);
-   ce-ce_mode = ce_mode_from_stat(ce, st.st_mode);
-   if (remove_cache_entry_at(pos)  0)
-   die(_(unable to remove .gitmodules from index));
-   if (write_sha1_file(buf.buf, buf.len, blob_type, ce-sha1))
-   die(_(adding updated .gitmodules failed));
-   if (add_cache_entry(ce, ADD_CACHE_OK_TO_ADD|ADD_CACHE_OK_TO_REPLACE))
+   if (add_file_to_cache(.gitmodules, 0))
die(_(staging updated .gitmodules failed));
 }
 
-- 
1.8.4.msysgit.0.12.g88f5ed0


--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v4 03/14] buitin/describe.c: use new hash map implementation

2013-11-07 Thread Karsten Blees
Signed-off-by: Karsten Blees bl...@dcon.de
Signed-off-by: Junio C Hamano gits...@pobox.com
---
 builtin/describe.c | 53 -
 1 file changed, 24 insertions(+), 29 deletions(-)

diff --git a/builtin/describe.c b/builtin/describe.c
index 6f62109..0b2cef4 100644
--- a/builtin/describe.c
+++ b/builtin/describe.c
@@ -6,7 +6,7 @@
 #include exec_cmd.h
 #include parse-options.h
 #include diff.h
-#include hash.h
+#include hashmap.h
 #include argv-array.h
 
 #define SEEN   (1u  0)
@@ -25,7 +25,7 @@ static int longformat;
 static int first_parent;
 static int abbrev = -1; /* unspecified */
 static int max_candidates = 10;
-static struct hash_table names;
+static struct hashmap names;
 static int have_util;
 static const char *pattern;
 static int always;
@@ -37,7 +37,7 @@ static const char *diff_index_args[] = {
 };
 
 struct commit_name {
-   struct commit_name *next;
+   struct hashmap_entry entry;
unsigned char peeled[20];
struct tag *tag;
unsigned prio:2; /* annotated tag = 2, tag = 1, head = 0 */
@@ -50,6 +50,12 @@ static const char *prio_names[] = {
head, lightweight, annotated,
 };
 
+static int commit_name_cmp(const struct commit_name *cn1,
+   const struct commit_name *cn2, const void *peeled)
+{
+   return hashcmp(cn1-peeled, peeled ? peeled : cn2-peeled);
+}
+
 static inline unsigned int hash_sha1(const unsigned char *sha1)
 {
unsigned int hash;
@@ -59,21 +65,9 @@ static inline unsigned int hash_sha1(const unsigned char 
*sha1)
 
 static inline struct commit_name *find_commit_name(const unsigned char *peeled)
 {
-   struct commit_name *n = lookup_hash(hash_sha1(peeled), names);
-   while (n  !!hashcmp(peeled, n-peeled))
-   n = n-next;
-   return n;
-}
-
-static int set_util(void *chain, void *data)
-{
-   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;
+   struct commit_name key;
+   hashmap_entry_init(key, hash_sha1(peeled));
+   return hashmap_get(names, key, peeled);
 }
 
 static int replace_name(struct commit_name *e,
@@ -118,16 +112,10 @@ static void add_to_known_names(const char *path,
struct tag *tag = NULL;
if (replace_name(e, prio, sha1, tag)) {
if (!e) {
-   void **pos;
e = xmalloc(sizeof(struct commit_name));
hashcpy(e-peeled, peeled);
-   pos = insert_hash(hash_sha1(peeled), e, names);
-   if (pos) {
-   e-next = *pos;
-   *pos = e;
-   } else {
-   e-next = NULL;
-   }
+   hashmap_entry_init(e, hash_sha1(peeled));
+   hashmap_add(names, e);
e-path = NULL;
}
e-tag = tag;
@@ -292,7 +280,14 @@ static void describe(const char *arg, int last_one)
fprintf(stderr, _(searching to describe %s\n), arg);
 
if (!have_util) {
-   for_each_hash(names, set_util, NULL);
+   struct hashmap_iter iter;
+   struct commit *c;
+   struct commit_name *n = hashmap_iter_first(names, iter);
+   for (; n; n = hashmap_iter_next(iter)) {
+   c = lookup_commit_reference_gently(n-peeled, 1);
+   if (c)
+   c-util = n;
+   }
have_util = 1;
}
 
@@ -463,9 +458,9 @@ int cmd_describe(int argc, const char **argv, const char 
*prefix)
return cmd_name_rev(args.argc, args.argv, prefix);
}
 
-   init_hash(names);
+   hashmap_init(names, (hashmap_cmp_fn) commit_name_cmp, 0);
for_each_rawref(get_name, NULL);
-   if (!names.nr  !always)
+   if (!names.size  !always)
die(_(No names found, cannot describe anything.));
 
if (argc == 0) {
-- 
1.8.4.msysgit.0.12.g88f5ed0

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v4 02/14] add a hashtable implementation that supports O(1) removal

2013-11-07 Thread Karsten Blees
The existing hashtable implementation (in hash.[ch]) uses open addressing
(i.e. resolve hash collisions by distributing entries across the table).
Thus, removal is difficult to implement with less than O(n) complexity.
Resolving collisions of entries with identical hashes (e.g. via chaining)
is left to the client code.

Add a hashtable implementation that supports O(1) removal and is slightly
easier to use due to builtin entry chaining.

Supports all basic operations init, free, get, add, remove and iteration.

Also includes ready-to-use hash functions based on the public domain FNV-1
algorithm (http://www.isthe.com/chongo/tech/comp/fnv).

The per-entry data structure (hashmap_entry) is piggybacked in front of
the client's data structure to save memory. See test-hashmap.c for usage
examples.

The hashtable is resized by a factor of four when 80% full. With these
settings, average memory consumption is about 2/3 of hash.[ch], and
insertion is about twice as fast due to less frequent resizing.

Lookups are also slightly faster, because entries are strictly confined to
their bucket (i.e. no data of other buckets needs to be traversed).

Signed-off-by: Karsten Blees bl...@dcon.de
Signed-off-by: Junio C Hamano gits...@pobox.com
---
 Documentation/technical/api-hashmap.txt | 237 ++
 Makefile|   3 +
 hashmap.c   | 212 
 hashmap.h   |  72 +++
 t/t0011-hashmap.sh  | 236 ++
 test-hashmap.c  | 340 
 6 files changed, 1100 insertions(+)
 create mode 100644 Documentation/technical/api-hashmap.txt
 create mode 100644 hashmap.c
 create mode 100644 hashmap.h
 create mode 100755 t/t0011-hashmap.sh
 create mode 100644 test-hashmap.c

diff --git a/Documentation/technical/api-hashmap.txt 
b/Documentation/technical/api-hashmap.txt
new file mode 100644
index 000..fc46e56
--- /dev/null
+++ b/Documentation/technical/api-hashmap.txt
@@ -0,0 +1,237 @@
+hashmap API
+===
+
+The hashmap API is a generic implementation of hash-based key-value mappings.
+
+Data Structures
+---
+
+`struct hashmap`::
+
+   The hash table structure.
++
+The `size` member keeps track of the total number of entries. The `cmpfn`
+member is a function used to compare two entries for equality. The `table` and
+`tablesize` members store the hash table and its size, respectively.
+
+`struct hashmap_entry`::
+
+   An opaque structure representing an entry in the hash table, which must
+   be used as first member of user data structures. Ideally it should be
+   followed by an int-sized member to prevent unused memory on 64-bit
+   systems due to alignment.
++
+The `hash` member is the entry's hash code and the `next` member points to the
+next entry in case of collisions (i.e. if multiple entries map to the same
+bucket).
+
+`struct hashmap_iter`::
+
+   An iterator structure, to be used with hashmap_iter_* functions.
+
+Types
+-
+
+`int (*hashmap_cmp_fn)(const void *entry, const void *entry_or_key, const void 
*keydata)`::
+
+   User-supplied function to test two hashmap entries for equality. Shall
+   return 0 if the entries are equal.
++
+This function is always called with non-NULL `entry` / `entry_or_key`
+parameters that have the same hash code. When looking up an entry, the `key`
+and `keydata` parameters to hashmap_get and hashmap_remove are always passed
+as second and third argument, respectively. Otherwise, `keydata` is NULL.
+
+`void (*hashmap_free_fn)(void *entry)`::
+
+   User-supplied function to free a hashmap_entry. If entries are simply
+   malloc'ed memory, use stdlib's free() function.
+
+Functions
+-
+
+`unsigned int strhash(const char *buf)`::
+`unsigned int strihash(const char *buf)`::
+`unsigned int memhash(const void *buf, size_t len)`::
+`unsigned int memihash(const void *buf, size_t len)`::
+
+   Ready-to-use hash functions for strings, using the FNV-1 algorithm (see
+   http://www.isthe.com/chongo/tech/comp/fnv).
++
+`strhash` and `strihash` take 0-terminated strings, while `memhash` and
+`memihash` operate on arbitrary-length memory.
++
+`strihash` and `memihash` are case insensitive versions.
+
+`void hashmap_init(struct hashmap *map, hashmap_cmp_fn equals_function, size_t 
initial_size)`::
+
+   Initializes a hashmap structure.
++
+`map` is the hashmap to initialize.
++
+The `equals_function` can be specified to compare two entries for equality.
+If NULL, entries are considered equal if their hash codes are equal.
++
+If the total number of entries is known in advance, the `initial_size`
+parameter may be used to preallocate a sufficiently large table and thus
+prevent expensive resizing. If 0, the table is dynamically resized.
+
+`void hashmap_free(struct hashmap *map, hashmap_free_fn free_function)`::
+
+   Frees a 

[PATCH v4 04/14] diffcore-rename.c: move code around to prepare for the next patch

2013-11-07 Thread Karsten Blees
No actual code changes, just move hash_filespec up and outdent part of
find_identical_files.

Signed-off-by: Karsten Blees bl...@dcon.de
Signed-off-by: Junio C Hamano gits...@pobox.com
---
 diffcore-rename.c | 98 +++
 1 file changed, 49 insertions(+), 49 deletions(-)

diff --git a/diffcore-rename.c b/diffcore-rename.c
index 6c7a72f..008a60c 100644
--- a/diffcore-rename.c
+++ b/diffcore-rename.c
@@ -248,6 +248,18 @@ struct file_similarity {
struct file_similarity *next;
 };
 
+static unsigned int hash_filespec(struct diff_filespec *filespec)
+{
+   unsigned int hash;
+   if (!filespec-sha1_valid) {
+   if (diff_populate_filespec(filespec, 0))
+   return 0;
+   hash_sha1_file(filespec-data, filespec-size, blob, 
filespec-sha1);
+   }
+   memcpy(hash, filespec-sha1, sizeof(hash));
+   return hash;
+}
+
 static int find_identical_files(struct file_similarity *src,
struct file_similarity *dst,
struct diff_options *options)
@@ -258,46 +270,46 @@ static int find_identical_files(struct file_similarity 
*src,
 * Walk over all the destinations ...
 */
do {
-   struct diff_filespec *target = dst-filespec;
-   struct file_similarity *p, *best;
-   int i = 100, best_score = -1;
-
-   /*
-* .. to find the best source match
-*/
-   best = NULL;
-   for (p = src; p; p = p-next) {
-   int score;
-   struct diff_filespec *source = p-filespec;
-
-   /* False hash collision? */
-   if (hashcmp(source-sha1, target-sha1))
-   continue;
-   /* Non-regular files? If so, the modes must match! */
-   if (!S_ISREG(source-mode) || !S_ISREG(target-mode)) {
-   if (source-mode != target-mode)
-   continue;
-   }
-   /* Give higher scores to sources that haven't been used 
already */
-   score = !source-rename_used;
-   if (source-rename_used  options-detect_rename != 
DIFF_DETECT_COPY)
-   continue;
-   score += basename_same(source, target);
-   if (score  best_score) {
-   best = p;
-   best_score = score;
-   if (score == 2)
-   break;
-   }
+   struct diff_filespec *target = dst-filespec;
+   struct file_similarity *p, *best;
+   int i = 100, best_score = -1;
 
-   /* Too many identical alternatives? Pick one */
-   if (!--i)
-   break;
+   /*
+* .. to find the best source match
+*/
+   best = NULL;
+   for (p = src; p; p = p-next) {
+   int score;
+   struct diff_filespec *source = p-filespec;
+
+   /* False hash collision? */
+   if (hashcmp(source-sha1, target-sha1))
+   continue;
+   /* Non-regular files? If so, the modes must match! */
+   if (!S_ISREG(source-mode) || !S_ISREG(target-mode)) {
+   if (source-mode != target-mode)
+   continue;
}
-   if (best) {
-   record_rename_pair(dst-index, best-index, MAX_SCORE);
-   renames++;
+   /* Give higher scores to sources that haven't been used already 
*/
+   score = !source-rename_used;
+   if (source-rename_used  options-detect_rename != 
DIFF_DETECT_COPY)
+   continue;
+   score += basename_same(source, target);
+   if (score  best_score) {
+   best = p;
+   best_score = score;
+   if (score == 2)
+   break;
}
+
+   /* Too many identical alternatives? Pick one */
+   if (!--i)
+   break;
+   }
+   if (best) {
+   record_rename_pair(dst-index, best-index, MAX_SCORE);
+   renames++;
+   }
} while ((dst = dst-next) != NULL);
return renames;
 }
@@ -343,18 +355,6 @@ static int find_same_files(void *ptr, void *data)
return ret;
 }
 
-static unsigned int hash_filespec(struct diff_filespec *filespec)
-{
-   unsigned int hash;
-   if (!filespec-sha1_valid) {
-   if (diff_populate_filespec(filespec, 0))
-   return 0;
-   

[PATCH v4 05/14] diffcore-rename.c: simplify finding exact renames

2013-11-07 Thread Karsten Blees
The find_exact_renames function currently only uses the hash table for
grouping, i.e.:

1. add sources
2. add destinations
3. iterate all buckets, per bucket:
4. split sources from destinations
5. iterate destinations, per destination:
6. iterate sources to find best match

This can be simplified by utilizing the lookup functionality of the hash
table, i.e.:

1. add sources
2. iterate destinations, per destination:
3. lookup sources matching the current destination
4. iterate sources to find best match

This saves several iterations and file_similarity allocations for the
destinations.

Signed-off-by: Karsten Blees bl...@dcon.de
Signed-off-by: Junio C Hamano gits...@pobox.com
---
 diffcore-rename.c | 75 +++
 1 file changed, 20 insertions(+), 55 deletions(-)

diff --git a/diffcore-rename.c b/diffcore-rename.c
index 008a60c..cfeb408 100644
--- a/diffcore-rename.c
+++ b/diffcore-rename.c
@@ -243,7 +243,7 @@ static int score_compare(const void *a_, const void *b_)
 }
 
 struct file_similarity {
-   int src_dst, index;
+   int index;
struct diff_filespec *filespec;
struct file_similarity *next;
 };
@@ -260,25 +260,21 @@ static unsigned int hash_filespec(struct diff_filespec 
*filespec)
return hash;
 }
 
-static int find_identical_files(struct file_similarity *src,
-   struct file_similarity *dst,
+static int find_identical_files(struct hash_table *srcs,
+   int dst_index,
struct diff_options *options)
 {
int renames = 0;
 
-   /*
-* Walk over all the destinations ...
-*/
-   do {
-   struct diff_filespec *target = dst-filespec;
+   struct diff_filespec *target = rename_dst[dst_index].two;
struct file_similarity *p, *best;
int i = 100, best_score = -1;
 
/*
-* .. to find the best source match
+* Find the best source match for specified destination.
 */
best = NULL;
-   for (p = src; p; p = p-next) {
+   for (p = lookup_hash(hash_filespec(target), srcs); p; p = p-next) {
int score;
struct diff_filespec *source = p-filespec;
 
@@ -307,61 +303,28 @@ static int find_identical_files(struct file_similarity 
*src,
break;
}
if (best) {
-   record_rename_pair(dst-index, best-index, MAX_SCORE);
+   record_rename_pair(dst_index, best-index, MAX_SCORE);
renames++;
}
-   } while ((dst = dst-next) != NULL);
return renames;
 }
 
-static void free_similarity_list(struct file_similarity *p)
+static int free_similarity_list(void *p, void *unused)
 {
while (p) {
struct file_similarity *entry = p;
-   p = p-next;
+   p = entry-next;
free(entry);
}
+   return 0;
 }
 
-static int find_same_files(void *ptr, void *data)
-{
-   int ret;
-   struct file_similarity *p = ptr;
-   struct file_similarity *src = NULL, *dst = NULL;
-   struct diff_options *options = data;
-
-   /* Split the hash list up into sources and destinations */
-   do {
-   struct file_similarity *entry = p;
-   p = p-next;
-   if (entry-src_dst  0) {
-   entry-next = src;
-   src = entry;
-   } else {
-   entry-next = dst;
-   dst = entry;
-   }
-   } while (p);
-
-   /*
-* If we have both sources *and* destinations, see if
-* we can match them up
-*/
-   ret = (src  dst) ? find_identical_files(src, dst, options) : 0;
-
-   /* Free the hashes and return the number of renames found */
-   free_similarity_list(src);
-   free_similarity_list(dst);
-   return ret;
-}
-
-static void insert_file_table(struct hash_table *table, int src_dst, int 
index, struct diff_filespec *filespec)
+static void insert_file_table(struct hash_table *table, int index, struct 
diff_filespec *filespec)
 {
void **pos;
unsigned int hash;
struct file_similarity *entry = xmalloc(sizeof(*entry));
 
-   entry-src_dst = src_dst;
entry-index = index;
entry-filespec = filespec;
entry-next = NULL;
@@ -385,24 +348,26 @@ static void insert_file_table(struct hash_table *table, 
int src_dst, int index,
  */
 static int find_exact_renames(struct diff_options *options)
 {
-   int i;
+   int i, renames = 0;
struct hash_table file_table;
 
+   /* Add all sources to the hash table */
init_hash(file_table);
-   preallocate_hash(file_table, rename_src_nr + rename_dst_nr);
+   preallocate_hash(file_table, rename_src_nr);
for (i = 0; i  rename_src_nr; i++)
-   insert_file_table(file_table, -1, i, rename_src[i].p-one);
+ 

[PATCH v4 06/14] diffcore-rename.c: use new hash map implementation

2013-11-07 Thread Karsten Blees
Signed-off-by: Karsten Blees bl...@dcon.de
Signed-off-by: Junio C Hamano gits...@pobox.com
---
 diffcore-rename.c | 48 +---
 1 file changed, 13 insertions(+), 35 deletions(-)

diff --git a/diffcore-rename.c b/diffcore-rename.c
index cfeb408..d996c6a 100644
--- a/diffcore-rename.c
+++ b/diffcore-rename.c
@@ -4,7 +4,7 @@
 #include cache.h
 #include diff.h
 #include diffcore.h
-#include hash.h
+#include hashmap.h
 #include progress.h
 
 /* Table of rename/copy destinations */
@@ -243,9 +243,9 @@ static int score_compare(const void *a_, const void *b_)
 }
 
 struct file_similarity {
+   struct hashmap_entry entry;
int index;
struct diff_filespec *filespec;
-   struct file_similarity *next;
 };
 
 static unsigned int hash_filespec(struct diff_filespec *filespec)
@@ -260,21 +260,22 @@ static unsigned int hash_filespec(struct diff_filespec 
*filespec)
return hash;
 }
 
-static int find_identical_files(struct hash_table *srcs,
+static int find_identical_files(struct hashmap *srcs,
int dst_index,
struct diff_options *options)
 {
int renames = 0;
 
struct diff_filespec *target = rename_dst[dst_index].two;
-   struct file_similarity *p, *best;
+   struct file_similarity *p, *best, dst;
int i = 100, best_score = -1;
 
/*
 * Find the best source match for specified destination.
 */
best = NULL;
-   for (p = lookup_hash(hash_filespec(target), srcs); p; p = p-next) {
+   hashmap_entry_init(dst, hash_filespec(target));
+   for (p = hashmap_get(srcs, dst, NULL); p; p = hashmap_get_next(srcs, 
p)) {
int score;
struct diff_filespec *source = p-filespec;
 
@@ -309,34 +310,15 @@ static int find_identical_files(struct hash_table *srcs,
return renames;
 }
 
-static int free_similarity_list(void *p, void *unused)
+static void insert_file_table(struct hashmap *table, int index, struct 
diff_filespec *filespec)
 {
-   while (p) {
-   struct file_similarity *entry = p;
-   p = entry-next;
-   free(entry);
-   }
-   return 0;
-}
-
-static void insert_file_table(struct hash_table *table, int index, struct 
diff_filespec *filespec)
-{
-   void **pos;
-   unsigned int hash;
struct file_similarity *entry = xmalloc(sizeof(*entry));
 
entry-index = index;
entry-filespec = filespec;
-   entry-next = NULL;
-
-   hash = hash_filespec(filespec);
-   pos = insert_hash(hash, entry, table);
 
-   /* We already had an entry there? */
-   if (pos) {
-   entry-next = *pos;
-   *pos = entry;
-   }
+   hashmap_entry_init(entry, hash_filespec(filespec));
+   hashmap_add(table, entry);
 }
 
 /*
@@ -349,11 +331,10 @@ static void insert_file_table(struct hash_table *table, 
int index, struct diff_f
 static int find_exact_renames(struct diff_options *options)
 {
int i, renames = 0;
-   struct hash_table file_table;
+   struct hashmap file_table;
 
/* Add all sources to the hash table */
-   init_hash(file_table);
-   preallocate_hash(file_table, rename_src_nr);
+   hashmap_init(file_table, NULL, rename_src_nr);
for (i = 0; i  rename_src_nr; i++)
insert_file_table(file_table, i, rename_src[i].p-one);
 
@@ -361,11 +342,8 @@ static int find_exact_renames(struct diff_options *options)
for (i = 0; i  rename_dst_nr; i++)
renames += find_identical_files(file_table, i, options);
 
-   /* Free source file_similarity chains */
-   for_each_hash(file_table, free_similarity_list, options);
-
-   /* .. and free the hash data structure */
-   free_hash(file_table);
+   /* Free the hash data structure and entries */
+   hashmap_free(file_table, free);
 
return renames;
 }
-- 
1.8.4.msysgit.0.12.g88f5ed0

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v4 07/14] name-hash.c: use new hash map implementation for directories

2013-11-07 Thread Karsten Blees
Signed-off-by: Karsten Blees bl...@dcon.de
Signed-off-by: Junio C Hamano gits...@pobox.com
---
 cache.h |  3 ++-
 name-hash.c | 77 +++--
 2 files changed, 20 insertions(+), 60 deletions(-)

diff --git a/cache.h b/cache.h
index d1f3c71..84e9ad6 100644
--- a/cache.h
+++ b/cache.h
@@ -4,6 +4,7 @@
 #include git-compat-util.h
 #include strbuf.h
 #include hash.h
+#include hashmap.h
 #include advice.h
 #include gettext.h
 #include convert.h
@@ -278,7 +279,7 @@ struct index_state {
unsigned name_hash_initialized : 1,
 initialized : 1;
struct hash_table name_hash;
-   struct hash_table dir_hash;
+   struct hashmap dir_hash;
 };
 
 extern struct index_state the_index;
diff --git a/name-hash.c b/name-hash.c
index e5b6e1a..ae636f8 100644
--- a/name-hash.c
+++ b/name-hash.c
@@ -8,49 +8,28 @@
 #define NO_THE_INDEX_COMPATIBILITY_MACROS
 #include cache.h
 
-/*
- * This removes bit 5 if bit 6 is set.
- *
- * That will make US-ASCII characters hash to their upper-case
- * equivalent. We could easily do this one whole word at a time,
- * but that's for future worries.
- */
-static inline unsigned char icase_hash(unsigned char c)
-{
-   return c  ~((c  0x40)  1);
-}
-
-static unsigned int hash_name(const char *name, int namelen)
-{
-   unsigned int hash = 0x123;
-
-   while (namelen--) {
-   unsigned char c = *name++;
-   c = icase_hash(c);
-   hash = hash*101 + c;
-   }
-   return hash;
-}
-
 struct dir_entry {
-   struct dir_entry *next;
+   struct hashmap_entry ent;
struct dir_entry *parent;
struct cache_entry *ce;
int nr;
unsigned int namelen;
 };
 
+static int dir_entry_cmp(const struct dir_entry *e1,
+   const struct dir_entry *e2, const char *name)
+{
+   return e1-namelen != e2-namelen || strncasecmp(e1-ce-name,
+   name ? name : e2-ce-name, e1-namelen);
+}
+
 static struct dir_entry *find_dir_entry(struct index_state *istate,
const char *name, unsigned int namelen)
 {
-   unsigned int hash = hash_name(name, namelen);
-   struct dir_entry *dir;
-
-   for (dir = lookup_hash(hash, istate-dir_hash); dir; dir = dir-next)
-   if (dir-namelen == namelen 
-   !strncasecmp(dir-ce-name, name, namelen))
-   return dir;
-   return NULL;
+   struct dir_entry key;
+   hashmap_entry_init(key, memihash(name, namelen));
+   key.namelen = namelen;
+   return hashmap_get(istate-dir_hash, key, name);
 }
 
 static struct dir_entry *hash_dir_entry(struct index_state *istate,
@@ -84,18 +63,11 @@ static struct dir_entry *hash_dir_entry(struct index_state 
*istate,
dir = find_dir_entry(istate, ce-name, namelen);
if (!dir) {
/* not found, create it and add to hash table */
-   void **pdir;
-   unsigned int hash = hash_name(ce-name, namelen);
-
dir = xcalloc(1, sizeof(struct dir_entry));
+   hashmap_entry_init(dir, memihash(ce-name, namelen));
dir-namelen = namelen;
dir-ce = ce;
-
-   pdir = insert_hash(hash, dir, istate-dir_hash);
-   if (pdir) {
-   dir-next = *pdir;
-   *pdir = dir;
-   }
+   hashmap_add(istate-dir_hash, dir);
 
/* recursively add missing parent directories */
dir-parent = hash_dir_entry(istate, ce, namelen);
@@ -134,7 +106,7 @@ static void hash_index_entry(struct index_state *istate, 
struct cache_entry *ce)
return;
ce-ce_flags |= CE_HASHED;
ce-next = NULL;
-   hash = hash_name(ce-name, ce_namelen(ce));
+   hash = memihash(ce-name, ce_namelen(ce));
pos = insert_hash(hash, ce, istate-name_hash);
if (pos) {
ce-next = *pos;
@@ -153,6 +125,7 @@ static void lazy_init_name_hash(struct index_state *istate)
return;
if (istate-cache_nr)
preallocate_hash(istate-name_hash, istate-cache_nr);
+   hashmap_init(istate-dir_hash, (hashmap_cmp_fn) dir_entry_cmp, 0);
for (nr = 0; nr  istate-cache_nr; nr++)
hash_index_entry(istate, istate-cache[nr]);
istate-name_hash_initialized = 1;
@@ -247,7 +220,7 @@ struct cache_entry *index_dir_exists(struct index_state 
*istate, const char *nam
 
 struct cache_entry *index_file_exists(struct index_state *istate, const char 
*name, int namelen, int icase)
 {
-   unsigned int hash = hash_name(name, namelen);
+   unsigned int hash = memihash(name, namelen);
struct cache_entry *ce;
 
lazy_init_name_hash(istate);
@@ -270,26 +243,12 @@ struct cache_entry *index_name_exists(struct index_state 
*istate, const char *na
return index_file_exists(istate, name, namelen, icase);
 }
 

[PATCH v4 08/14] name-hash.c: remove unreferenced directory entries

2013-11-07 Thread Karsten Blees
The new hashmap implementation supports remove, so remove and free
directory entries that are no longer referenced by active cache entries.

Signed-off-by: Karsten Blees bl...@dcon.de
Signed-off-by: Junio C Hamano gits...@pobox.com
---
 name-hash.c | 15 ---
 1 file changed, 8 insertions(+), 7 deletions(-)

diff --git a/name-hash.c b/name-hash.c
index ae636f8..116f56d 100644
--- a/name-hash.c
+++ b/name-hash.c
@@ -86,15 +86,16 @@ static void add_dir_entry(struct index_state *istate, 
struct cache_entry *ce)
 static void remove_dir_entry(struct index_state *istate, struct cache_entry 
*ce)
 {
/*
-* Release reference to the directory entry (and parents if 0).
-*
-* Note: we do not remove / free the entry because there's no
-* hash.[ch]::remove_hash and dir-next may point to other entries
-* that are still valid, so we must not free the memory.
+* Release reference to the directory entry. If 0, remove and continue
+* with parent directory.
 */
struct dir_entry *dir = hash_dir_entry(istate, ce, ce_namelen(ce));
-   while (dir  dir-nr  !(--dir-nr))
-   dir = dir-parent;
+   while (dir  !(--dir-nr)) {
+   struct dir_entry *parent = dir-parent;
+   hashmap_remove(istate-dir_hash, dir, NULL);
+   free(dir);
+   dir = parent;
+   }
 }
 
 static void hash_index_entry(struct index_state *istate, struct cache_entry 
*ce)
-- 
1.8.4.msysgit.0.12.g88f5ed0

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v4 09/14] name-hash.c: use new hash map implementation for cache entries

2013-11-07 Thread Karsten Blees
Note: the ce-next = NULL; in unpack-trees.c::do_add_entry can safely be
removed, as ce-next (now ce-ent.next) is always properly initialized in
name-hash.c::hash_index_entry.

Signed-off-by: Karsten Blees bl...@dcon.de
Signed-off-by: Junio C Hamano gits...@pobox.com
---
 cache.h|  8 +---
 name-hash.c| 24 
 unpack-trees.c |  1 -
 3 files changed, 13 insertions(+), 20 deletions(-)

diff --git a/cache.h b/cache.h
index 84e9ad6..cedc7ae 100644
--- a/cache.h
+++ b/cache.h
@@ -131,12 +131,12 @@ struct stat_data {
 };
 
 struct cache_entry {
+   struct hashmap_entry ent;
struct stat_data ce_stat_data;
unsigned int ce_mode;
unsigned int ce_flags;
unsigned int ce_namelen;
unsigned char sha1[20];
-   struct cache_entry *next;
char name[FLEX_ARRAY]; /* more */
 };
 
@@ -203,7 +203,9 @@ static inline void copy_cache_entry(struct cache_entry *dst,
unsigned int state = dst-ce_flags  CE_STATE_MASK;
 
/* Don't copy hash chain and name */
-   memcpy(dst, src, offsetof(struct cache_entry, next));
+   memcpy(dst-ce_stat_data, src-ce_stat_data,
+   offsetof(struct cache_entry, name) -
+   offsetof(struct cache_entry, ce_stat_data));
 
/* Restore the hash state */
dst-ce_flags = (dst-ce_flags  ~CE_STATE_MASK) | state;
@@ -278,7 +280,7 @@ struct index_state {
struct cache_time timestamp;
unsigned name_hash_initialized : 1,
 initialized : 1;
-   struct hash_table name_hash;
+   struct hashmap name_hash;
struct hashmap dir_hash;
 };
 
diff --git a/name-hash.c b/name-hash.c
index 116f56d..1ec82a3 100644
--- a/name-hash.c
+++ b/name-hash.c
@@ -100,19 +100,11 @@ static void remove_dir_entry(struct index_state *istate, 
struct cache_entry *ce)
 
 static void hash_index_entry(struct index_state *istate, struct cache_entry 
*ce)
 {
-   void **pos;
-   unsigned int hash;
-
if (ce-ce_flags  CE_HASHED)
return;
ce-ce_flags |= CE_HASHED;
-   ce-next = NULL;
-   hash = memihash(ce-name, ce_namelen(ce));
-   pos = insert_hash(hash, ce, istate-name_hash);
-   if (pos) {
-   ce-next = *pos;
-   *pos = ce;
-   }
+   hashmap_entry_init(ce, memihash(ce-name, ce_namelen(ce)));
+   hashmap_add(istate-name_hash, ce);
 
if (ignore_case  !(ce-ce_flags  CE_UNHASHED))
add_dir_entry(istate, ce);
@@ -124,8 +116,7 @@ static void lazy_init_name_hash(struct index_state *istate)
 
if (istate-name_hash_initialized)
return;
-   if (istate-cache_nr)
-   preallocate_hash(istate-name_hash, istate-cache_nr);
+   hashmap_init(istate-name_hash, NULL, istate-cache_nr);
hashmap_init(istate-dir_hash, (hashmap_cmp_fn) dir_entry_cmp, 0);
for (nr = 0; nr  istate-cache_nr; nr++)
hash_index_entry(istate, istate-cache[nr]);
@@ -221,18 +212,19 @@ struct cache_entry *index_dir_exists(struct index_state 
*istate, const char *nam
 
 struct cache_entry *index_file_exists(struct index_state *istate, const char 
*name, int namelen, int icase)
 {
-   unsigned int hash = memihash(name, namelen);
struct cache_entry *ce;
+   struct hashmap_entry key;
 
lazy_init_name_hash(istate);
-   ce = lookup_hash(hash, istate-name_hash);
 
+   hashmap_entry_init(key, memihash(name, namelen));
+   ce = hashmap_get(istate-name_hash, key, NULL);
while (ce) {
if (!(ce-ce_flags  CE_UNHASHED)) {
if (same_name(ce, name, namelen, icase))
return ce;
}
-   ce = ce-next;
+   ce = hashmap_get_next(istate-name_hash, ce);
}
return NULL;
 }
@@ -250,6 +242,6 @@ void free_name_hash(struct index_state *istate)
return;
istate-name_hash_initialized = 0;
 
-   free_hash(istate-name_hash);
+   hashmap_free(istate-name_hash, NULL);
hashmap_free(istate-dir_hash, free);
 }
diff --git a/unpack-trees.c b/unpack-trees.c
index ad3e9a0..f8985d4 100644
--- a/unpack-trees.c
+++ b/unpack-trees.c
@@ -110,7 +110,6 @@ static void do_add_entry(struct unpack_trees_options *o, 
struct cache_entry *ce,
if (set  CE_REMOVE)
set |= CE_WT_REMOVE;
 
-   ce-next = NULL;
ce-ce_flags = (ce-ce_flags  ~clear) | set;
add_index_entry(o-result, ce,
ADD_CACHE_OK_TO_ADD | ADD_CACHE_OK_TO_REPLACE);
-- 
1.8.4.msysgit.0.12.g88f5ed0

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v4 10/14] name-hash.c: remove cache entries instead of marking them CE_UNHASHED

2013-11-07 Thread Karsten Blees
The new hashmap implementation supports remove, so really remove unused
cache entries from the name hashmap instead of just marking them.

The CE_UNHASHED flag and CE_STATE_MASK are no longer needed.

Keep the CE_HASHED flag to prevent adding entries twice.

Signed-off-by: Karsten Blees bl...@dcon.de
Signed-off-by: Junio C Hamano gits...@pobox.com
---
 cache.h|  6 ++
 name-hash.c| 46 ++
 read-cache.c   |  2 +-
 unpack-trees.c |  2 +-
 4 files changed, 26 insertions(+), 30 deletions(-)

diff --git a/cache.h b/cache.h
index cedc7ae..05b8011 100644
--- a/cache.h
+++ b/cache.h
@@ -160,7 +160,6 @@ struct cache_entry {
 #define CE_ADDED (1  19)
 
 #define CE_HASHED(1  20)
-#define CE_UNHASHED  (1  21)
 #define CE_WT_REMOVE (1  22) /* remove in work directory */
 #define CE_CONFLICTED(1  23)
 
@@ -196,11 +195,10 @@ struct pathspec;
  * Copy the sha1 and stat state of a cache entry from one to
  * another. But we never change the name, or the hash state!
  */
-#define CE_STATE_MASK (CE_HASHED | CE_UNHASHED)
 static inline void copy_cache_entry(struct cache_entry *dst,
const struct cache_entry *src)
 {
-   unsigned int state = dst-ce_flags  CE_STATE_MASK;
+   unsigned int state = dst-ce_flags  CE_HASHED;
 
/* Don't copy hash chain and name */
memcpy(dst-ce_stat_data, src-ce_stat_data,
@@ -208,7 +206,7 @@ static inline void copy_cache_entry(struct cache_entry *dst,
offsetof(struct cache_entry, ce_stat_data));
 
/* Restore the hash state */
-   dst-ce_flags = (dst-ce_flags  ~CE_STATE_MASK) | state;
+   dst-ce_flags = (dst-ce_flags  ~CE_HASHED) | state;
 }
 
 static inline unsigned create_ce_flags(unsigned stage)
diff --git a/name-hash.c b/name-hash.c
index 1ec82a3..8871d8e 100644
--- a/name-hash.c
+++ b/name-hash.c
@@ -106,17 +106,29 @@ static void hash_index_entry(struct index_state *istate, 
struct cache_entry *ce)
hashmap_entry_init(ce, memihash(ce-name, ce_namelen(ce)));
hashmap_add(istate-name_hash, ce);
 
-   if (ignore_case  !(ce-ce_flags  CE_UNHASHED))
+   if (ignore_case)
add_dir_entry(istate, ce);
 }
 
+static int cache_entry_cmp(const struct cache_entry *ce1,
+   const struct cache_entry *ce2, const void *remove)
+{
+   /*
+* For remove_name_hash, find the exact entry (pointer equality); for
+* index_name_exists, find all entries with matching hash code and
+* decide whether the entry matches in same_name.
+*/
+   return remove ? !(ce1 == ce2) : 0;
+}
+
 static void lazy_init_name_hash(struct index_state *istate)
 {
int nr;
 
if (istate-name_hash_initialized)
return;
-   hashmap_init(istate-name_hash, NULL, istate-cache_nr);
+   hashmap_init(istate-name_hash, (hashmap_cmp_fn) cache_entry_cmp,
+   istate-cache_nr);
hashmap_init(istate-dir_hash, (hashmap_cmp_fn) dir_entry_cmp, 0);
for (nr = 0; nr  istate-cache_nr; nr++)
hash_index_entry(istate, istate-cache[nr]);
@@ -125,31 +137,19 @@ static void lazy_init_name_hash(struct index_state 
*istate)
 
 void add_name_hash(struct index_state *istate, struct cache_entry *ce)
 {
-   /* if already hashed, add reference to directory entries */
-   if (ignore_case  (ce-ce_flags  CE_STATE_MASK) == CE_STATE_MASK)
-   add_dir_entry(istate, ce);
-
-   ce-ce_flags = ~CE_UNHASHED;
if (istate-name_hash_initialized)
hash_index_entry(istate, ce);
 }
 
-/*
- * We don't actually *remove* it, we can just mark it invalid so that
- * we won't find it in lookups.
- *
- * Not only would we have to search the lists (simple enough), but
- * we'd also have to rehash other hash buckets in case this makes the
- * hash bucket empty (common). So it's much better to just mark
- * it.
- */
 void remove_name_hash(struct index_state *istate, struct cache_entry *ce)
 {
-   /* if already hashed, release reference to directory entries */
-   if (ignore_case  (ce-ce_flags  CE_STATE_MASK) == CE_HASHED)
-   remove_dir_entry(istate, ce);
+   if (!istate-name_hash_initialized || !(ce-ce_flags  CE_HASHED))
+   return;
+   ce-ce_flags = ~CE_HASHED;
+   hashmap_remove(istate-name_hash, ce, ce);
 
-   ce-ce_flags |= CE_UNHASHED;
+   if (ignore_case)
+   remove_dir_entry(istate, ce);
 }
 
 static int slow_same_name(const char *name1, int len1, const char *name2, int 
len2)
@@ -220,10 +220,8 @@ struct cache_entry *index_file_exists(struct index_state 
*istate, const char *na
hashmap_entry_init(key, memihash(name, namelen));
ce = hashmap_get(istate-name_hash, key, NULL);
while (ce) {
-   if (!(ce-ce_flags  CE_UNHASHED)) {
-   if (same_name(ce, name, namelen, 

[PATCH v4 11/14] remove old hash.[ch] implementation

2013-11-07 Thread Karsten Blees
Signed-off-by: Karsten Blees bl...@dcon.de
Signed-off-by: Junio C Hamano gits...@pobox.com
---
 Documentation/technical/api-hash.txt |  52 -
 Makefile |   2 -
 cache.h  |   1 -
 hash.c   | 110 ---
 hash.h   |  50 
 test-hashmap.c   |  84 --
 6 files changed, 299 deletions(-)
 delete mode 100644 Documentation/technical/api-hash.txt
 delete mode 100644 hash.c
 delete mode 100644 hash.h

diff --git a/Documentation/technical/api-hash.txt 
b/Documentation/technical/api-hash.txt
deleted file mode 100644
index e5061e0..000
--- a/Documentation/technical/api-hash.txt
+++ /dev/null
@@ -1,52 +0,0 @@
-hash API
-
-
-The hash API is a collection of simple hash table functions. Users are expected
-to implement their own hashing.
-
-Data Structures

-
-`struct hash_table`::
-
-   The hash table structure. The `array` member points to the hash table
-   entries. The `size` member counts the total number of valid and invalid
-   entries in the table. The `nr` member keeps track of the number of
-   valid entries.
-
-`struct hash_table_entry`::
-
-   An opaque structure representing an entry in the hash table. The `hash`
-   member is the entry's hash key and the `ptr` member is the entry's
-   value.
-
-Functions
--
-
-`init_hash`::
-
-   Initialize the hash table.
-
-`free_hash`::
-
-   Release memory associated with the hash table.
-
-`insert_hash`::
-
-   Insert a pointer into the hash table. If an entry with that hash
-   already exists, a pointer to the existing entry's value is returned.
-   Otherwise NULL is returned.  This allows callers to implement
-   chaining, etc.
-
-`lookup_hash`::
-
-   Lookup an entry in the hash table. If an entry with that hash exists
-   the entry's value is returned. Otherwise NULL is returned.
-
-`for_each_hash`::
-
-   Call a function for each entry in the hash table. The function is
-   expected to take the entry's value as its only argument and return an
-   int. If the function returns a negative int the loop is aborted
-   immediately.  Otherwise, the return value is accumulated and the sum
-   returned upon completion of the loop.
diff --git a/Makefile b/Makefile
index 05c5b4d..5101426 100644
--- a/Makefile
+++ b/Makefile
@@ -676,7 +676,6 @@ LIB_H += git-compat-util.h
 LIB_H += gpg-interface.h
 LIB_H += graph.h
 LIB_H += grep.h
-LIB_H += hash.h
 LIB_H += hashmap.h
 LIB_H += help.h
 LIB_H += http.h
@@ -808,7 +807,6 @@ LIB_OBJS += gettext.o
 LIB_OBJS += gpg-interface.o
 LIB_OBJS += graph.o
 LIB_OBJS += grep.o
-LIB_OBJS += hash.o
 LIB_OBJS += hashmap.o
 LIB_OBJS += help.o
 LIB_OBJS += hex.o
diff --git a/cache.h b/cache.h
index 05b8011..27067b8 100644
--- a/cache.h
+++ b/cache.h
@@ -3,7 +3,6 @@
 
 #include git-compat-util.h
 #include strbuf.h
-#include hash.h
 #include hashmap.h
 #include advice.h
 #include gettext.h
diff --git a/hash.c b/hash.c
deleted file mode 100644
index 749ecfe..000
--- a/hash.c
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * Some generic hashing helpers.
- */
-#include cache.h
-#include hash.h
-
-/*
- * Look up a hash entry in the hash table. Return the pointer to
- * the existing entry, or the empty slot if none existed. The caller
- * can then look at the (*ptr) to see whether it existed or not.
- */
-static struct hash_table_entry *lookup_hash_entry(unsigned int hash, const 
struct hash_table *table)
-{
-   unsigned int size = table-size, nr = hash % size;
-   struct hash_table_entry *array = table-array;
-
-   while (array[nr].ptr) {
-   if (array[nr].hash == hash)
-   break;
-   nr++;
-   if (nr = size)
-   nr = 0;
-   }
-   return array + nr;
-}
-
-
-/*
- * Insert a new hash entry pointer into the table.
- *
- * If that hash entry already existed, return the pointer to
- * the existing entry (and the caller can create a list of the
- * pointers or do anything else). If it didn't exist, return
- * NULL (and the caller knows the pointer has been inserted).
- */
-static void **insert_hash_entry(unsigned int hash, void *ptr, struct 
hash_table *table)
-{
-   struct hash_table_entry *entry = lookup_hash_entry(hash, table);
-
-   if (!entry-ptr) {
-   entry-ptr = ptr;
-   entry-hash = hash;
-   table-nr++;
-   return NULL;
-   }
-   return entry-ptr;
-}
-
-static void grow_hash_table(struct hash_table *table)
-{
-   unsigned int i;
-   unsigned int old_size = table-size, new_size;
-   struct hash_table_entry *old_array = table-array, *new_array;
-
-   new_size = alloc_nr(old_size);
-   new_array = xcalloc(sizeof(struct hash_table_entry), new_size);
-   

Warning Your Mailbox Has Exceeded Quota Limit

2013-11-07 Thread Kell, Todd



Dear user,

Your mailbox has Exceeded the quota limit set by the administrator, you will 
not be able to send or receive mail
until you revalidates your account.

Please click the link below or copy paste to your browser to validate your 
mailbox.
http://tinylink.net/quotalimit

Failure to do this will result limited access to your mailbox and failure to 
update your account within 48-hours,
of this update notification, your account will be closed permanently.

Thanks
System Administrator.--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v4 14/14] read-cache.c: fix memory leaks caused by removed cache entries

2013-11-07 Thread Karsten Blees
When cache_entry structs are removed from index_state.cache, they are not
properly freed. Freeing those entries wasn't possible before because we
couldn't remove them from index_state.name_hash.

Now that we _do_ remove the entries from name_hash, we can also free them.
Add 'free(cache_entry)' to all call sites of name-hash.c::remove_name_hash
in read-cache.c (we could free() directly in remove_name_hash(), but
name-hash.c isn't concerned with cache_entry allocation at all).

Accessing a cache_entry after removing it from the index is now no longer
allowed, as the memory has been freed. The following functions need minor
fixes (typically by copying ce-name before use):
 - builtin/rm.c::cmd_rm
 - builtin/update-index.c::do_reupdate
 - read-cache.c::read_index_unmerged
 - resolve-undo.c::unmerge_index_entry_at

Signed-off-by: Karsten Blees bl...@dcon.de
---
 builtin/rm.c   | 2 +-
 builtin/update-index.c | 5 -
 read-cache.c   | 8 ++--
 resolve-undo.c | 7 +--
 4 files changed, 16 insertions(+), 6 deletions(-)

diff --git a/builtin/rm.c b/builtin/rm.c
index 3a0e0ea..171f37c 100644
--- a/builtin/rm.c
+++ b/builtin/rm.c
@@ -311,7 +311,7 @@ int cmd_rm(int argc, const char **argv, const char *prefix)
if (!match_pathspec_depth(pathspec, ce-name, ce_namelen(ce), 
0, seen))
continue;
ALLOC_GROW(list.entry, list.nr + 1, list.alloc);
-   list.entry[list.nr].name = ce-name;
+   list.entry[list.nr].name = xstrdup(ce-name);
list.entry[list.nr].is_submodule = S_ISGITLINK(ce-ce_mode);
if (list.entry[list.nr++].is_submodule 
!is_staging_gitmodules_ok())
diff --git a/builtin/update-index.c b/builtin/update-index.c
index b654d27..acd992d 100644
--- a/builtin/update-index.c
+++ b/builtin/update-index.c
@@ -559,6 +559,7 @@ static int do_reupdate(int ac, const char **av,
const struct cache_entry *ce = active_cache[pos];
struct cache_entry *old = NULL;
int save_nr;
+   const char *path;
 
if (ce_stage(ce) || !ce_path_match(ce, pathspec))
continue;
@@ -575,7 +576,9 @@ static int do_reupdate(int ac, const char **av,
 * or worse yet 'allow_replace', active_nr may decrease.
 */
save_nr = active_nr;
-   update_one(ce-name);
+   path = xstrdup(ce-name);
+   update_one(path);
+   free(path);
if (save_nr != active_nr)
goto redo;
}
diff --git a/read-cache.c b/read-cache.c
index 00af9ad..3f735f3 100644
--- a/read-cache.c
+++ b/read-cache.c
@@ -47,6 +47,7 @@ static void replace_index_entry(struct index_state *istate, 
int nr, struct cache
struct cache_entry *old = istate-cache[nr];
 
remove_name_hash(istate, old);
+   free(old);
set_index_entry(istate, nr, ce);
istate-cache_changed = 1;
 }
@@ -478,6 +479,7 @@ int remove_index_entry_at(struct index_state *istate, int 
pos)
 
record_resolve_undo(istate, ce);
remove_name_hash(istate, ce);
+   free(ce);
istate-cache_changed = 1;
istate-cache_nr--;
if (pos = istate-cache_nr)
@@ -499,8 +501,10 @@ void remove_marked_cache_entries(struct index_state 
*istate)
unsigned int i, j;
 
for (i = j = 0; i  istate-cache_nr; i++) {
-   if (ce_array[i]-ce_flags  CE_REMOVE)
+   if (ce_array[i]-ce_flags  CE_REMOVE) {
remove_name_hash(istate, ce_array[i]);
+   free(ce_array[i]);
+   }
else
ce_array[j++] = ce_array[i];
}
@@ -1894,7 +1898,7 @@ int read_index_unmerged(struct index_state *istate)
new_ce-ce_mode = ce-ce_mode;
if (add_index_entry(istate, new_ce, 0))
return error(%s: cannot drop to stage #0,
-ce-name);
+new_ce-name);
i = index_name_pos(istate, new_ce-name, len);
}
return unmerged;
diff --git a/resolve-undo.c b/resolve-undo.c
index c09b006..49ebaaf 100644
--- a/resolve-undo.c
+++ b/resolve-undo.c
@@ -119,6 +119,7 @@ int unmerge_index_entry_at(struct index_state *istate, int 
pos)
struct string_list_item *item;
struct resolve_undo_info *ru;
int i, err = 0, matched;
+   char *name;
 
if (!istate-resolve_undo)
return pos;
@@ -138,20 +139,22 @@ int unmerge_index_entry_at(struct index_state *istate, 
int pos)
if (!ru)
return pos;
matched = ce-ce_flags  CE_MATCHED;
+   name = xstrdup(ce-name);
remove_index_entry_at(istate, pos);
for (i = 0; i  3; i++) {
struct cache_entry *nce;
if (!ru-mode[i])
  

[PATCH v4 13/14] builtin/update-index.c: cleanup update_one

2013-11-07 Thread Karsten Blees
do_reupdate calls update_one with a cache_entry.name, there's no need for
the extra sanitation / normalization that happens in prefix_path.
cmd_update_index calls update_one with an already prefixed path, no need to
prefix_path twice.

Remove the extra prefix_path from update_one. Also remove the now unused
'prefix' and 'prefix_length' parameters.

As of d089eba setup: sanitize absolute and funny paths in get_pathspec(),
prefix_path uncoditionally returns a copy, even if the passed in path isn't
changed. Lets unconditionally free() the result.

Signed-off-by: Karsten Blees bl...@dcon.de
---
 builtin/update-index.c | 36 +++-
 1 file changed, 15 insertions(+), 21 deletions(-)

diff --git a/builtin/update-index.c b/builtin/update-index.c
index d180d80..b654d27 100644
--- a/builtin/update-index.c
+++ b/builtin/update-index.c
@@ -274,36 +274,32 @@ static void chmod_path(int flip, const char *path)
die(git update-index: cannot chmod %cx '%s', flip, path);
 }
 
-static void update_one(const char *path, const char *prefix, int prefix_length)
+static void update_one(const char *path)
 {
-   const char *p = prefix_path(prefix, prefix_length, path);
-   if (!verify_path(p)) {
+   if (!verify_path(path)) {
fprintf(stderr, Ignoring path %s\n, path);
-   goto free_return;
+   return;
}
if (mark_valid_only) {
-   if (mark_ce_flags(p, CE_VALID, mark_valid_only == MARK_FLAG))
+   if (mark_ce_flags(path, CE_VALID, mark_valid_only == MARK_FLAG))
die(Unable to mark file %s, path);
-   goto free_return;
+   return;
}
if (mark_skip_worktree_only) {
-   if (mark_ce_flags(p, CE_SKIP_WORKTREE, mark_skip_worktree_only 
== MARK_FLAG))
+   if (mark_ce_flags(path, CE_SKIP_WORKTREE, 
mark_skip_worktree_only == MARK_FLAG))
die(Unable to mark file %s, path);
-   goto free_return;
+   return;
}
 
if (force_remove) {
-   if (remove_file_from_cache(p))
+   if (remove_file_from_cache(path))
die(git update-index: unable to remove %s, path);
report(remove '%s', path);
-   goto free_return;
+   return;
}
-   if (process_path(p))
+   if (process_path(path))
die(Unable to process path %s, path);
report(add '%s', path);
- free_return:
-   if (p  path || p  path + strlen(path))
-   free((char *)p);
 }
 
 static void read_index_info(int line_termination)
@@ -579,7 +575,7 @@ static int do_reupdate(int ac, const char **av,
 * or worse yet 'allow_replace', active_nr may decrease.
 */
save_nr = active_nr;
-   update_one(ce-name, NULL, 0);
+   update_one(ce-name);
if (save_nr != active_nr)
goto redo;
}
@@ -836,11 +832,10 @@ int cmd_update_index(int argc, const char **argv, const 
char *prefix)
 
setup_work_tree();
p = prefix_path(prefix, prefix_length, path);
-   update_one(p, NULL, 0);
+   update_one(p);
if (set_executable_bit)
chmod_path(set_executable_bit, p);
-   if (p  path || p  path + strlen(path))
-   free((char *)p);
+   free(p);
ctx.argc--;
ctx.argv++;
break;
@@ -879,11 +874,10 @@ int cmd_update_index(int argc, const char **argv, const 
char *prefix)
strbuf_swap(buf, nbuf);
}
p = prefix_path(prefix, prefix_length, buf.buf);
-   update_one(p, NULL, 0);
+   update_one(p);
if (set_executable_bit)
chmod_path(set_executable_bit, p);
-   if (p  buf.buf || p  buf.buf + buf.len)
-   free((char *)p);
+   free(p);
}
strbuf_release(nbuf);
strbuf_release(buf);
-- 
1.8.4.msysgit.0.12.g88f5ed0

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC/PATCH] Add interpret-trailers builtin

2013-11-07 Thread Christian Couder
On Wed, Nov 6, 2013 at 9:42 PM, Junio C Hamano gits...@pobox.com wrote:
 Christian Couder chrisc...@tuxfamily.org writes:
 From: Junio C Hamano gits...@pobox.com

 But that is insufficient to emulate what we do, no?  I.e. append
 unless the last one is from the same person we are about to add.

 Yeah, but, with DONT_REPEAT_PREVIOUS, it would be possible using:

 [trailer signoff]
  key = Signed-off-by:
  if_exist = dont_repeat_previous
  if_missing = append
  command = echo $GIT_COMMITTER_NAME $GIT_COMMITTER_EMAIL'

 Anything is possible, but possible does not justify it is better
 way than other possible ways.

 What are the plausible values for if_missing?  If if_missing needs
 prepend, for example, in addition to append, does it mean
 if_exist also needs corresponding prepend variant for the value
 dont_repeat_previous you would give to if_exist?

Yeah, we could add prepend to the possible values for if_missing and
also other values that prepend instead of append to if_exist.
But I am not sure they would be as useful.

If we think they are useful, then maybe we could instead add another
configuration to say if we want to append or prepend or put in the
middle, and change the others to make them clearer.
For example we could have:

where = (after | middle | before)
if_exist = (add_if_different | add_if_neighbor_different | add |
overwrite | do_nothing)
if_missing = (do_nothing | add)

(The default being the first choice.)

 Having two that are seemingly independent configuration does not
 seem to be helping in reducing complexity (by keeping settings that
 can be independently set orthogonal, by saying if the other rule
 decides to add, do we append, prepend, insert at the middle?, for
 example).

I am not sure I understand what you mean.
In my opinion, if we want to use just one configuration, instead of 2
or 3, it will not reduce complexity.

Maybe we could parse something like:

style = if_exist:add_if_different:after, if_missing:add:before

or like:

style = (append | prepend | insert | append_unless regexp |
prepend_unless regexp | insert_unless regexp)

with regexp being a regexp where $KEY is the key and $VALUE is the
value, so you can say: append_unless ^$KEY[:=]$VALUE.*

or like:

style = (append_if cmd | prepend_if cmd | insert_if cmd)

with cmd being a shell command that should exit with code 0.

(The command would be passed the existing trailers in stdin.
So you could say things like: append_if true or append_if tail -1 |
grep -v '$KEY: $VALUE')

But if we want to keep things simple, I think what I suggest first
above is probably best.

And by the way, later we might add add_if_match regexp or
add_if_true cmd to if_exist and if_missing, so we could still
be as powerful as the other styles.

 How would one differentiate between there is a field with that key
 and there is a field with that key, value combination with a
 single if_exist?  Add another variable if_exist_exact?

if_exist = do_nothing would mean: do nothing if there is a field
with that key
if_exist = overwrite would mean: overwrite the existing value of a
field with that key
if_exist = add would mean: add if there is one or more fields with
that key (whatever the value(s), so the value(s) could be the same)
if_exist = add_if_different would mean: add only if there is no
field with the same key, value pair
if_exist = add_if_different_neighbor would mean: add only if there
is no field with the same key, value pair where we are going to add

if_missing = do_nothing would mean: do nothing if there is no field
with that key
if_missing= add would mean: add if there is no field with that key

where = after would mean: if we decide to add, we will put the
trailer after the other trailers
where = middle would mean: if we decide to add, we will put the
trailer in the middle of the other trailers
where = before would mean: if we decide to add, we will put the
trailer before the other trailers

In my opinion, that should be enough for most use cases.

It is true that some people might want something more complex (like
adding only if there is no value for the same key that match a given
regexp) or something stranger like adding only if there is already a
field with the same key, value pair.

But we can take care of these special cases later if they actually happen.
Then we will hopefully have more experience.
And we could add things like add_if_no_value_match regexp or
add_if cmd to if_exist and if_missing .

Thanks,
Christian.
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: What's cooking in git.git (Nov 2013, #02; Wed, 6)

2013-11-07 Thread Marc Branchaud
On 13-11-06 07:01 PM, Junio C Hamano wrote:
 
 There is a proposed rewording of advice message from git push
 patch, which is tentatively queued near the tip of 'pu' for now; it
 would be nice to get a few more sets of eyeballs.  I am not sure if
 we should merge it before the 1.8.5 final, yet (we have i18n to
 worry about, among other things).

I was all set to comment (having been asked so nicely!), but the patch in pu
looks like the last v3 version, of which there was some discussion[1] that
I believe should result in a v4.  I prefer to hold off commenting until the
next update.

[1] http://thread.gmane.org/gmane.comp.version-control.git/235713/focus=237384

M.

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 0/2] Improve gitignore documentation wrt excluded directories

2013-11-07 Thread Karsten Blees
Also here:
https://github.com/kblees/git/commits/kb/gitignore-doc

These two patches were the result of a discussion mid-october [1] that I almost 
forgot about...now including an example as suggested by Jeff.

[1] http://thread.gmane.org/gmane.comp.version-control.git/235753/focus=235856

Karsten Blees (2):
  gitignore.txt: fix documentation of ** patterns
  gitignore.txt: clarify recursive nature of excluded directories

 Documentation/gitignore.txt | 24 +++-
 1 file changed, 19 insertions(+), 5 deletions(-)

-- 
1.8.4.msysgit.0.12.g88f5ed0

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 1/2] gitignore.txt: fix documentation of ** patterns

2013-11-07 Thread Karsten Blees
** means bold in ASCIIDOC, so we need to escape it.

Signed-off-by: Karsten Blees bl...@dcon.de
---
 Documentation/gitignore.txt | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/Documentation/gitignore.txt b/Documentation/gitignore.txt
index 54e334e..f971960 100644
--- a/Documentation/gitignore.txt
+++ b/Documentation/gitignore.txt
@@ -113,12 +113,12 @@ full pathname may have special meaning:
 
  - A leading `**` followed by a slash means match in all
directories. For example, `**/foo` matches file or directory
-   `foo` anywhere, the same as pattern `foo`. **/foo/bar
+   `foo` anywhere, the same as pattern `foo`. `**/foo/bar`
matches file or directory `bar` anywhere that is directly
under directory `foo`.
 
- - A trailing /** matches everything inside. For example,
-   abc/** matches all files inside directory abc, relative
+ - A trailing `/**` matches everything inside. For example,
+   `abc/**` matches all files inside directory `abc`, relative
to the location of the `.gitignore` file, with infinite depth.
 
  - A slash followed by two consecutive asterisks then a slash
-- 
1.8.4.msysgit.0.12.g88f5ed0

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 2/2] gitignore.txt: clarify recursive nature of excluded directories

2013-11-07 Thread Karsten Blees
Additionally, precedence of negated patterns is exactly as outlined in
the DESCRIPTION section, we don't need to repeat this.

Signed-off-by: Karsten Blees bl...@dcon.de
---
 Documentation/gitignore.txt | 18 --
 1 file changed, 16 insertions(+), 2 deletions(-)

diff --git a/Documentation/gitignore.txt b/Documentation/gitignore.txt
index f971960..5ecc48e 100644
--- a/Documentation/gitignore.txt
+++ b/Documentation/gitignore.txt
@@ -79,8 +79,9 @@ PATTERN FORMAT
 
  - An optional prefix `!` which negates the pattern; any
matching file excluded by a previous pattern will become
-   included again.  If a negated pattern matches, this will
-   override lower precedence patterns sources.
+   included again. It is not possible to re-include a file if a parent
+   directory of that file is excluded (i.e. excluding a directory
+   will recursively and irrevocably exclude the entire content).
Put a backslash (`\`) in front of the first `!` for patterns
that begin with a literal `!`, for example, `\!important!.txt`.
 
@@ -182,6 +183,19 @@ Another example:
 The second .gitignore prevents Git from ignoring
 `arch/foo/kernel/vmlinux.lds.S`.
 
+Example to exclude everything except a specific directory `foo/bar`
+(note the `/*` - without the slash, the wildcard would also exclude
+everything within `foo/bar`):
+
+--
+$ cat .gitignore
+# exclude everything except directory foo/bar
+/*
+!/foo
+/foo/*
+!/foo/bar
+--
+
 SEE ALSO
 
 linkgit:git-rm[1],
-- 
1.8.4.msysgit.0.12.g88f5ed0

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Request: timeout option for remote operations, esp. git fetch

2013-11-07 Thread H. Peter Anvin
When a remote server is unavailable or very slow, some git commands can
stall out indefinitely.  It would be a very good thing if remote
commands -- but especially git fetch -- could be given a timeout.

-hpa
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 1/3] for-each-ref: introduce %C(...) for color

2013-11-07 Thread Junio C Hamano
Ramkumar Ramachandra artag...@gmail.com writes:

 Junio C Hamano wrote:
 ... users of for-each-ref format will be _more_ familiar with
 formats used by for-each-ref, and it would make a lot more sense to
 keep the syntactic resemblance between existing features to show
 magic things in for-each-ref and the new feature to show color
 (which is merely one new magic to the vocabulary in the context of
 for-each-ref), no?

 Okay, so what do you suggest in place of %C(...)?

If %(authordate) is I want to see the author date here, and
%(authordate:short) is I want to see the author date here in the
short form, you would expect I want colored output in green to be
spelled as %(color:green), or something, perhaps?



--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v3] push: Enhance unspecified push default warning

2013-11-07 Thread Junio C Hamano
Matthieu Moy matthieu@grenoble-inp.fr writes:

 Jonathan Nieder jrnie...@gmail.com writes:

  When push.default is set to 'matching', git will push local branches
  to remote branches that already exist with the same (matching) name.

 Yes, that's better than the original patch (and remains two lines).

 +   In Git 2.0 the new push.default of 'simple' will push only the 
 current\n
 +   branch to the same remote branch used by git pull.   A push will\n
 +   only succeed if the remote and local branches have the same name.\n

 while you can see that it is not telling a lie if you read it twice,
 will only succeed if feels somewhat roundabout.

... push only the current branch back to the branch of the
same name, but only if 'git pull' is set to pull from that
branch. Otherwise the push will fail.

 might be an improvement, but I dunno.

 I do not see much difference actually. I tend to prefer the original
 version: to me the expected behavior is to make push and pull
 essentially symetrical, and the fact that it fails if the branch is
 named differently is a safety feature comming on top of that.

 Perhaps:

  In Git 2.0 (or now, if push.default is set to 'simple'), git will behave
  more conservatively by pushing only the current branch to the 
 corresponding
  remote branch used by git pull, and only if the remote and local 
 branches
  have the same name.

 I prefered the original, as it had two sentences. Reading only the first
 one gave the important information.

Actually, to me, I found the two sentences the worst part in the
original.  It made it sound as if the default will be switching to
'upstream', and all readers need to read the second sentence that
clarifies that it is not the case, in a somewhat round-about
way---will only succeed if invites and otherwise...?

  In Git 2.0, git will default to a more conservative 'simple' behavior
  that only pushes the current branch.

 That's an option too, but I think mentionning git pull was a good
 idea.

Yes, mentioning git pull is a good idea throughout these
proposals.
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Colorize output

2013-11-07 Thread Nicolas
Hello,

I’m developping a git command in shell and I would like colorize the output.

I don’t find anything in git-sh-setup.

What is the best way for don’t reinvent the wheel?

Thanks in advance.

Best regards.
Nicolas.



signature.asc
Description: OpenPGP digital signature


Re: Colorize output

2013-11-07 Thread John Keeping
On Thu, Nov 07, 2013 at 07:10:11PM +0100, Nicolas wrote:
 I’m developping a git command in shell and I would like colorize the output.
 
 I don’t find anything in git-sh-setup.
 
 What is the best way for don’t reinvent the wheel?

I normally use git config --get-color ... either with standard colors
if my command is close to a standard command or with my own config keys
and sensible defaults.
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 1/2] gitignore.txt: fix documentation of ** patterns

2013-11-07 Thread Junio C Hamano
Karsten Blees karsten.bl...@gmail.com writes:

 ** means bold in ASCIIDOC, so we need to escape it.

 Signed-off-by: Karsten Blees bl...@dcon.de
 ---
  Documentation/gitignore.txt | 6 +++---
  1 file changed, 3 insertions(+), 3 deletions(-)

 diff --git a/Documentation/gitignore.txt b/Documentation/gitignore.txt
 index 54e334e..f971960 100644
 --- a/Documentation/gitignore.txt
 +++ b/Documentation/gitignore.txt
 @@ -113,12 +113,12 @@ full pathname may have special meaning:
  
   - A leading `**` followed by a slash means match in all
 directories. For example, `**/foo` matches file or directory
 -   `foo` anywhere, the same as pattern `foo`. **/foo/bar
 +   `foo` anywhere, the same as pattern `foo`. `**/foo/bar`
 matches file or directory `bar` anywhere that is directly
 under directory `foo`.
  
 - - A trailing /** matches everything inside. For example,
 -   abc/** matches all files inside directory abc, relative
 + - A trailing `/**` matches everything inside. For example,
 +   `abc/**` matches all files inside directory `abc`, relative
 to the location of the `.gitignore` file, with infinite depth.

All, including the quoting of `abc` that does not have anything to
do with the double-asterisk, look good; thanks.

  
   - A slash followed by two consecutive asterisks then a slash
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v3] push: Enhance unspecified push default warning

2013-11-07 Thread Matthieu Moy
Junio C Hamano gits...@pobox.com writes:

 Actually, to me, I found the two sentences the worst part in the
 original.  It made it sound as if the default will be switching to
 'upstream', and all readers need to read the second sentence that
 clarifies that it is not the case, in a somewhat round-about
 way---will only succeed if invites and otherwise...?

To me, this is not an issue given the audience (people too lazy to read
the docs): for them, current == simple == upstream modulo details
they're not interested about. The safety measure of simple is actually
here to make sure nothing wrong happens if they make the confusion.

But that's just a preference, I'm OK with your other proposal too.

-- 
Matthieu Moy
http://www-verimag.imag.fr/~moy/
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 2/2] gitignore.txt: clarify recursive nature of excluded directories

2013-11-07 Thread Junio C Hamano
Karsten Blees karsten.bl...@gmail.com writes:

 Additionally, precedence of negated patterns is exactly as outlined in
 the DESCRIPTION section, we don't need to repeat this.

Very good, thanks.

Even though I have a suspicion that somebody else may be able to
come up with a better phrase that does not sound unnecessarily
strongly than recursively and irrevocably, that somebody else is
not me, so I'll queue this as-is for now.


 Signed-off-by: Karsten Blees bl...@dcon.de
 ---
  Documentation/gitignore.txt | 18 --
  1 file changed, 16 insertions(+), 2 deletions(-)

 diff --git a/Documentation/gitignore.txt b/Documentation/gitignore.txt
 index f971960..5ecc48e 100644
 --- a/Documentation/gitignore.txt
 +++ b/Documentation/gitignore.txt
 @@ -79,8 +79,9 @@ PATTERN FORMAT
  
   - An optional prefix `!` which negates the pattern; any
 matching file excluded by a previous pattern will become
 -   included again.  If a negated pattern matches, this will
 -   override lower precedence patterns sources.
 +   included again. It is not possible to re-include a file if a parent
 +   directory of that file is excluded (i.e. excluding a directory
 +   will recursively and irrevocably exclude the entire content).
 Put a backslash (`\`) in front of the first `!` for patterns
 that begin with a literal `!`, for example, `\!important!.txt`.
  
 @@ -182,6 +183,19 @@ Another example:
  The second .gitignore prevents Git from ignoring
  `arch/foo/kernel/vmlinux.lds.S`.
  
 +Example to exclude everything except a specific directory `foo/bar`
 +(note the `/*` - without the slash, the wildcard would also exclude
 +everything within `foo/bar`):
 +
 +--
 +$ cat .gitignore
 +# exclude everything except directory foo/bar
 +/*
 +!/foo
 +/foo/*
 +!/foo/bar
 +--
 +
  SEE ALSO
  
  linkgit:git-rm[1],
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 2/2] gitignore.txt: clarify recursive nature of excluded directories

2013-11-07 Thread Junio C Hamano
Junio C Hamano gits...@pobox.com writes:

 Karsten Blees karsten.bl...@gmail.com writes:

 Additionally, precedence of negated patterns is exactly as outlined in
 the DESCRIPTION section, we don't need to repeat this.

 Very good, thanks.

 Even though I have a suspicion that somebody else may be able to
 come up with a better phrase that does not sound unnecessarily
 strongly than recursively and irrevocably, that somebody else is
 not me, so I'll queue this as-is for now.

Just in case somebody thinks about rephrasing, to me, these two
words sound heavier than the information they actually convey, and
that is why I said unnecessarily strong.

The key thing in the behaviour when a directory is excluded is that
it tells us to stop going into that directory, and there is no way
to override it with another .gitignore file somewhere inside,
because we are told not to even bother looking for it.  Recursively
and irrevocably may be an accurate description of the end result,
but that sounds more like a rule without a because; to a reader
(me), it lacks the aha, of course that comes from understanding
why.

 Signed-off-by: Karsten Blees bl...@dcon.de
 ---
  Documentation/gitignore.txt | 18 --
  1 file changed, 16 insertions(+), 2 deletions(-)

 diff --git a/Documentation/gitignore.txt b/Documentation/gitignore.txt
 index f971960..5ecc48e 100644
 --- a/Documentation/gitignore.txt
 +++ b/Documentation/gitignore.txt
 @@ -79,8 +79,9 @@ PATTERN FORMAT
  
   - An optional prefix `!` which negates the pattern; any
 matching file excluded by a previous pattern will become
 -   included again.  If a negated pattern matches, this will
 -   override lower precedence patterns sources.
 +   included again. It is not possible to re-include a file if a parent
 +   directory of that file is excluded (i.e. excluding a directory
 +   will recursively and irrevocably exclude the entire content).
 Put a backslash (`\`) in front of the first `!` for patterns
 that begin with a literal `!`, for example, `\!important!.txt`.
  
 @@ -182,6 +183,19 @@ Another example:
  The second .gitignore prevents Git from ignoring
  `arch/foo/kernel/vmlinux.lds.S`.
  
 +Example to exclude everything except a specific directory `foo/bar`
 +(note the `/*` - without the slash, the wildcard would also exclude
 +everything within `foo/bar`):
 +
 +--
 +$ cat .gitignore
 +# exclude everything except directory foo/bar
 +/*
 +!/foo
 +/foo/*
 +!/foo/bar
 +--
 +
  SEE ALSO
  
  linkgit:git-rm[1],
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 2/2] gitignore.txt: clarify recursive nature of excluded directories

2013-11-07 Thread Jeff King
On Thu, Nov 07, 2013 at 11:37:38AM -0800, Junio C Hamano wrote:

 Junio C Hamano gits...@pobox.com writes:
 
  Karsten Blees karsten.bl...@gmail.com writes:
 
  Additionally, precedence of negated patterns is exactly as outlined in
  the DESCRIPTION section, we don't need to repeat this.
 
  Very good, thanks.
 
  Even though I have a suspicion that somebody else may be able to
  come up with a better phrase that does not sound unnecessarily
  strongly than recursively and irrevocably, that somebody else is
  not me, so I'll queue this as-is for now.
 
 Just in case somebody thinks about rephrasing, to me, these two
 words sound heavier than the information they actually convey, and
 that is why I said unnecessarily strong.

I agree that it seems unnecessarily strong.  The word irrevocable to
me implies that it cannot ever be changed. But of course it is only
irrevocable for the particular run; you can always edit the .gitignore
file. :)

 The key thing in the behaviour when a directory is excluded is that
 it tells us to stop going into that directory, and there is no way
 to override it with another .gitignore file somewhere inside,
 because we are told not to even bother looking for it.  Recursively
 and irrevocably may be an accurate description of the end result,
 but that sounds more like a rule without a because; to a reader
 (me), it lacks the aha, of course that comes from understanding
 why.

I think it is more than just we do not descend and so do not read the
.gitignore file. I thought the previous discussion on this topic showed
that you cannot do:

  $ cat .gitignore
  foo
  !foo/bar

to see foo/bar.

- An optional prefix `!` which negates the pattern; any
  matching file excluded by a previous pattern will become
  -   included again.  If a negated pattern matches, this will
  -   override lower precedence patterns sources.
  +   included again. It is not possible to re-include a file if a parent
  +   directory of that file is excluded (i.e. excluding a directory
  +   will recursively and irrevocably exclude the entire content).
  Put a backslash (`\`) in front of the first `!` for patterns
  that begin with a literal `!`, for example, `\!important!.txt`.

How about:

  It is not possible to re-include a file if a parent directory of that
  file is excluded. Once git considers a directory excluded, it does not
  descend into the directory to consider its contents further.

  +Example to exclude everything except a specific directory `foo/bar`
  +(note the `/*` - without the slash, the wildcard would also exclude
  +everything within `foo/bar`):
  +
  +--
  +$ cat .gitignore
  +# exclude everything except directory foo/bar
  +/*
  +!/foo
  +/foo/*
  +!/foo/bar
  +--

That looks good to me. The simplest example would be handling a
top-level directory (i.e., ignore all except `/foo`). That is a subset
of what's happening above, and I think showing the general case is good.
I'd worry slightly that a non-astute reader might not figure out how to
simplify down to the top-level case, and we should have two examples. I
may just be overly pessimistic, though.

-Peff
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 2/2] gitignore.txt: clarify recursive nature of excluded directories

2013-11-07 Thread Karsten Blees
Am 07.11.2013 20:55, schrieb Jeff King:
 On Thu, Nov 07, 2013 at 11:37:38AM -0800, Junio C Hamano wrote:
 
 Junio C Hamano gits...@pobox.com writes:

 Karsten Blees karsten.bl...@gmail.com writes:

 Additionally, precedence of negated patterns is exactly as outlined in
 the DESCRIPTION section, we don't need to repeat this.

 Very good, thanks.

 Even though I have a suspicion that somebody else may be able to
 come up with a better phrase that does not sound unnecessarily
 strongly than recursively and irrevocably, that somebody else is
 not me, so I'll queue this as-is for now.

 Just in case somebody thinks about rephrasing, to me, these two
 words sound heavier than the information they actually convey, and
 that is why I said unnecessarily strong.
 
 I agree that it seems unnecessarily strong.  The word irrevocable to
 me implies that it cannot ever be changed. But of course it is only
 irrevocable for the particular run; you can always edit the .gitignore
 file. :)
 
 The key thing in the behaviour when a directory is excluded is that
 it tells us to stop going into that directory, and there is no way
 to override it with another .gitignore file somewhere inside,
 because we are told not to even bother looking for it.  Recursively
 and irrevocably may be an accurate description of the end result,
 but that sounds more like a rule without a because; to a reader
 (me), it lacks the aha, of course that comes from understanding
 why.
 
 I think it is more than just we do not descend and so do not read the
 .gitignore file. I thought the previous discussion on this topic showed
 that you cannot do:
 
   $ cat .gitignore
   foo
   !foo/bar
 
 to see foo/bar.


Yes, the pattern could be in .git/info/exclude and it still wouldn't work.
 
   - An optional prefix `!` which negates the pattern; any
 matching file excluded by a previous pattern will become
 -   included again.  If a negated pattern matches, this will
 -   override lower precedence patterns sources.
 +   included again. It is not possible to re-include a file if a parent
 +   directory of that file is excluded (i.e. excluding a directory
 +   will recursively and irrevocably exclude the entire content).
 Put a backslash (`\`) in front of the first `!` for patterns
 that begin with a literal `!`, for example, `\!important!.txt`.
 
 How about:
 
   It is not possible to re-include a file if a parent directory of that
   file is excluded. Once git considers a directory excluded, it does not
   descend into the directory to consider its contents further.
 

Hmm...an unsuspecting reader might still assume that it works in top-level 
.gitignore, given the precendence rules above...

How about this:

   It is not possible to re-include a file if a parent directory of that
   file is excluded. Git doesn't list excluded directories for performance
   reasons, so any patterns on contained files have no effect, no matter
   where they are defined.

 +Example to exclude everything except a specific directory `foo/bar`
 +(note the `/*` - without the slash, the wildcard would also exclude
 +everything within `foo/bar`):
 +
 +--
 +$ cat .gitignore
 +# exclude everything except directory foo/bar
 +/*
 +!/foo
 +/foo/*
 +!/foo/bar
 +--
 
 That looks good to me. The simplest example would be handling a
 top-level directory (i.e., ignore all except `/foo`). That is a subset
 of what's happening above, and I think showing the general case is good.
 I'd worry slightly that a non-astute reader might not figure out how to
 simplify down to the top-level case, and we should have two examples. I
 may just be overly pessimistic, though.
 
 -Peff
 

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 2/2] gitignore.txt: clarify recursive nature of excluded directories

2013-11-07 Thread Jeff King
On Thu, Nov 07, 2013 at 09:27:16PM +0100, Karsten Blees wrote:

  How about:
  
It is not possible to re-include a file if a parent directory of that
file is excluded. Once git considers a directory excluded, it does not
descend into the directory to consider its contents further.
  
 
 Hmm...an unsuspecting reader might still assume that it works in
 top-level .gitignore, given the precendence rules above...
 
 How about this:
 
It is not possible to re-include a file if a parent directory of that
file is excluded. Git doesn't list excluded directories for performance
reasons, so any patterns on contained files have no effect, no matter
where they are defined.

Yeah, I like that.

-Peff
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 2/2] gitignore.txt: clarify recursive nature of excluded directories

2013-11-07 Thread Karsten Blees
Additionally, precedence of negated patterns is exactly as outlined in
the DESCRIPTION section, we don't need to repeat this.

Signed-off-by: Karsten Blees bl...@dcon.de
---

I also force-pushed to git://github.com/kblees/git.git kb/gitignore-doc.

 Documentation/gitignore.txt | 19 +--
 1 file changed, 17 insertions(+), 2 deletions(-)

diff --git a/Documentation/gitignore.txt b/Documentation/gitignore.txt
index f971960..205e80e 100644
--- a/Documentation/gitignore.txt
+++ b/Documentation/gitignore.txt
@@ -79,8 +79,10 @@ PATTERN FORMAT
 
  - An optional prefix `!` which negates the pattern; any
matching file excluded by a previous pattern will become
-   included again.  If a negated pattern matches, this will
-   override lower precedence patterns sources.
+   included again. It is not possible to re-include a file if a parent
+   directory of that file is excluded. Git doesn't list excluded
+   directories for performance reasons, so any patterns on contained
+   files have no effect, no matter where they are defined.
Put a backslash (`\`) in front of the first `!` for patterns
that begin with a literal `!`, for example, `\!important!.txt`.
 
@@ -182,6 +184,19 @@ Another example:
 The second .gitignore prevents Git from ignoring
 `arch/foo/kernel/vmlinux.lds.S`.
 
+Example to exclude everything except a specific directory `foo/bar`
+(note the `/*` - without the slash, the wildcard would also exclude
+everything within `foo/bar`):
+
+--
+$ cat .gitignore
+# exclude everything except directory foo/bar
+/*
+!/foo
+/foo/*
+!/foo/bar
+--
+
 SEE ALSO
 
 linkgit:git-rm[1],
-- 
1.8.4.msysgit.1

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v4 02/14] add a hashtable implementation that supports O(1) removal

2013-11-07 Thread Junio C Hamano
Karsten Blees karsten.bl...@gmail.com writes:

 +`void hashmap_add(struct hashmap *map, void *entry)`::
 +
 + Adds a hashmap entry. This allows to add duplicate entries (i.e.
 + separate values with the same key according to hashmap_cmp_fn).
 ++
 +`map` is the hashmap structure.
 ++
 +`entry` is the entry to add.
 +
 +`void *hashmap_put(struct hashmap *map, void *entry)`::
 +
 + Adds or replaces a hashmap entry.
 ++
 +`map` is the hashmap structure.
 ++
 +`entry` is the entry to add or update.
 ++
 +Returns the previous entry, or NULL if not found (i.e. the entry was added).

What happens when there were duplicate entries previously added?
All are replaced?  One of them is randomly chosen and gets replaced?

With s/replaced/removed/, the same question applies to hashmap_remove().

I am guessing that we pick one at random and pretend as if other
duplicates do not exist is the answer, and I do not immediately
have an objection to that semantics, but whatever the rule is, it
needs to be spelled out.

 +`void *hashmap_remove(struct hashmap *map, const void *key, const void 
 *keydata)`::
 +
 + Removes a hashmap entry matching the specified key.
 ...
 +Usage example
 +-
 +
 +Here's a simple usage example that maps long keys to double values.
 +[source,c]
 +
 +struct hashmap map;
 +
 +struct long2double {
 + struct hashmap_entry ent; /* must be the first member! */
 + long key;
 + double value;
 +};
 +
 +static int long2double_cmp(const struct long2double *e1, const struct 
 long2double *e2, const void *unused)
 +{
 + return !(e1-key == e2-key);
 +}
 +
 +void long2double_init()

void long2double_init(void)

 +{
 + hashmap_init(map, (hashmap_cmp_fn) long2double_cmp, 0);
 +}
 +
 +void long2double_free()

Likewise.

 diff --git a/hashmap.c b/hashmap.c
 new file mode 100644
 index 000..3a9f8c1
 --- /dev/null
 +++ b/hashmap.c
 ...
 +unsigned int memhash(const void *buf, size_t len)
 +{
 + unsigned int hash = FNV32_BASE;
 + unsigned char *ucbuf = (unsigned char*) buf;

(unsigned char *)buf; pointer-asterisk does not stick to type.

 + while (len--) {
 + unsigned int c = *ucbuf++;
 + hash = (hash * FNV32_PRIME) ^ c;
 + }
 + return hash;
 +}
 +
 +unsigned int memihash(const void *buf, size_t len)
 +{
 + unsigned int hash = FNV32_BASE;
 + unsigned char *ucbuf = (unsigned char*) buf;
 + while (len--) {
 + unsigned int c = *ucbuf++;
 + if (c = 'a'  c = 'z')
 + c -= 'a' - 'A';
 + hash = (hash * FNV32_PRIME) ^ c;
 + }
 + return hash;
 +}
 +
 +#define HASHMAP_INITIAL_SIZE 64
 +/* grow / shrink by 2^2 */
 +#define HASHMAP_GROW 2
 +/* grow if  80% full (to 20%) */
 +#define HASHMAP_GROW_AT 1.25
 +/* shrink if  16.6% full (to 66.6%) */
 +#define HASHMAP_SHRINK_AT 6

May be I am too old fashioned, but seeing a floating-point constant
in our otherwise pretty-much integer-only code makes me feel uneasy.
gcc -S -O2 does seem to generate floating point instruction for
i but not for j:

extern void inspect(unsigned int i, unsigned int j);

void grow(unsigned int i, unsigned int j)
{
i *= 1.25;
j += j  2;
inspect(i, j);
}

Perhaps

#define HASHMAP_GROW_AT(current) ((current) + (current)  2)
#define HASHMAP_SHRINK_AT(current) ((current) * 6)
#define HASHMAP_GROW(current) ((current)  2)
#define HASHMAP_SHRINK(current) ((current)  2)

may alleviate my worries; I dunno.

 +
 +static inline int entry_equals(const struct hashmap *map,
 + const struct hashmap_entry *e1, const struct hashmap_entry *e2,
 + const void *keydata)
 +{
 + return (e1 == e2) || (e1-hash == e2-hash  !(*map-cmpfn)(e1, e2, 
 keydata));

Our code tends not to say this is a pointer to a function
explicitly, i.e.

!map-cmpfn(e1, e2, keydata)

is more in-line with our code and should also be sufficient.

 +}
 +
 +static inline unsigned int bucket(const struct hashmap *map,
 + const struct hashmap_entry *key)
 +{
 + return key-hash  (map-tablesize - 1);
 +}
 +
 +static void rehash(struct hashmap *map, unsigned int newsize)
 +{
 + unsigned int i, oldsize = map-tablesize;
 + struct hashmap_entry **oldtable = map-table;
 +
 + map-tablesize = newsize;
 + map-table = xcalloc(sizeof(struct hashmap_entry*), map-tablesize);

Even though multiplication is commutative, please match the official
function signature, i.e.

calloc(size_t nmemb, size_t size)

where the number of elements comes first and size of an element
comes next.  I.e.

xcalloc(map-tablesize, sizeof(struct hashmap_entry *));

Also don't forget the SP between type and asterisk.

 + for (i = 0; i  oldsize; i++) {
 + struct hashmap_entry *e = oldtable[i];
 + while (e) {
 + struct hashmap_entry *next = e-next;
 + unsigned int b = bucket(map, 

Re: [PATCH v4 13/14] builtin/update-index.c: cleanup update_one

2013-11-07 Thread Junio C Hamano
Karsten Blees karsten.bl...@gmail.com writes:

 - if (p  path || p  path + strlen(path))
 - free((char *)p);
 + free(p);

The non-const cast was there for a reason.  I'll locally fix it up
(there is another instance of the same) to get it compile before
queuing it on 'pu'.

Thanks.

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v4 14/14] read-cache.c: fix memory leaks caused by removed cache entries

2013-11-07 Thread Junio C Hamano
Karsten Blees karsten.bl...@gmail.com writes:

 diff --git a/builtin/update-index.c b/builtin/update-index.c
 index b654d27..acd992d 100644
 --- a/builtin/update-index.c
 +++ b/builtin/update-index.c
 @@ -559,6 +559,7 @@ static int do_reupdate(int ac, const char **av,
   const struct cache_entry *ce = active_cache[pos];
   struct cache_entry *old = NULL;
   int save_nr;
 + const char *path;
  
   if (ce_stage(ce) || !ce_path_match(ce, pathspec))
   continue;
 @@ -575,7 +576,9 @@ static int do_reupdate(int ac, const char **av,
* or worse yet 'allow_replace', active_nr may decrease.
*/
   save_nr = active_nr;
 - update_one(ce-name);
 + path = xstrdup(ce-name);
 + update_one(path);
 + free(path);
   if (save_nr != active_nr)
   goto redo;
   }

This also gets complaint from free() that does not want to free a
const pointer.  I'll fix it up locally to get it compile before
queuing it to 'pu'.

Thanks.
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Экстаз У молодицы гарантирован

2013-11-07 Thread sn_00_py
100% обеспечите королеве удовлетворение http://goo.gl/n5lfgw
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 1/5] compat/bswap.h: Fix build on cygwin, MinGW and msvc

2013-11-07 Thread Ramsay Jones

Signed-off-by: Ramsay Jones ram...@ramsay1.demon.co.uk
---
 compat/bswap.h | 97 --
 1 file changed, 68 insertions(+), 29 deletions(-)

diff --git a/compat/bswap.h b/compat/bswap.h
index ea1a9ed..c18a78e 100644
--- a/compat/bswap.h
+++ b/compat/bswap.h
@@ -17,7 +17,20 @@ static inline uint32_t default_swab32(uint32_t val)
((val  0x00ff)  24));
 }
 
+static inline uint64_t default_bswap64(uint64_t val)
+{
+   return (((val  (uint64_t)0x00ffULL)  56) |
+   ((val  (uint64_t)0xff00ULL)  40) |
+   ((val  (uint64_t)0x00ffULL)  24) |
+   ((val  (uint64_t)0xff00ULL)   8) |
+   ((val  (uint64_t)0x00ffULL)   8) |
+   ((val  (uint64_t)0xff00ULL)  24) |
+   ((val  (uint64_t)0x00ffULL)  40) |
+   ((val  (uint64_t)0xff00ULL)  56));
+}
+
 #undef bswap32
+#undef bswap64
 
 #if defined(__GNUC__)  (defined(__i386__) || defined(__x86_64__))
 
@@ -32,54 +45,80 @@ static inline uint32_t git_bswap32(uint32_t x)
return result;
 }
 
+#define bswap64 git_bswap64
+#if defined(__x86_64__)
+static inline uint64_t git_bswap64(uint64_t x)
+{
+   uint64_t result;
+   if (__builtin_constant_p(x))
+   result = default_bswap64(x);
+   else
+   __asm__(bswap %q0 : =r (result) : 0 (x));
+   return result;
+}
+#else
+static inline uint64_t git_bswap64(uint64_t x)
+{
+   union { uint64_t i64; uint32_t i32[2]; } tmp, result;
+   if (__builtin_constant_p(x))
+   result.i64 = default_bswap64(x);
+   else {
+   tmp.i64 = x;
+   result.i32[0] = git_bswap32(tmp.i32[1]);
+   result.i32[1] = git_bswap32(tmp.i32[0]);
+   }
+   return result.i64;
+}
+#endif
+
 #elif defined(_MSC_VER)  (defined(_M_IX86) || defined(_M_X64))
 
 #include stdlib.h
 
 #define bswap32(x) _byteswap_ulong(x)
+#define bswap64(x) _byteswap_uint64(x)
 
 #endif
 
-#ifdef bswap32
+#if defined(bswap32)
 
 #undef ntohl
 #undef htonl
 #define ntohl(x) bswap32(x)
 #define htonl(x) bswap32(x)
 
-#ifndef __BYTE_ORDER
-#  if defined(BYTE_ORDER)  defined(LITTLE_ENDIAN)  defined(BIG_ENDIAN)
-#  define __BYTE_ORDER BYTE_ORDER
-#  define __LITTLE_ENDIAN LITTLE_ENDIAN
-#  define __BIG_ENDIAN BIG_ENDIAN
-#  else
-#  error Cannot determine endianness
-#  endif
+#endif
+
+#if defined(bswap64)
+
+#undef ntohll
+#undef htonll
+#define ntohll(x) bswap64(x)
+#define htonll(x) bswap64(x)
+
+#else
+
+#undef ntohll
+#undef htonll
+
+#if !defined(__BYTE_ORDER)
+# if defined(BYTE_ORDER)  defined(LITTLE_ENDIAN)  defined(BIG_ENDIAN)
+#  define __BYTE_ORDER BYTE_ORDER
+#  define __LITTLE_ENDIAN LITTLE_ENDIAN
+#  define __BIG_ENDIAN BIG_ENDIAN
+# endif
+#endif
+
+#if !defined(__BYTE_ORDER)
+# error Cannot determine endianness
 #endif
 
 #if __BYTE_ORDER == __BIG_ENDIAN
 # define ntohll(n) (n)
 # define htonll(n) (n)
-#elif __BYTE_ORDER == __LITTLE_ENDIAN
-#  if defined(__GNUC__)  defined(__GLIBC__)
-#  include byteswap.h
-#  else /* GNUC  GLIBC */
-static inline uint64_t bswap_64(uint64_t val)
-{
-   return ((val  (uint64_t)0x00ffULL)  56)
-   | ((val  (uint64_t)0xff00ULL)  40)
-   | ((val  (uint64_t)0x00ffULL)  24)
-   | ((val  (uint64_t)0xff00ULL)   8)
-   | ((val  (uint64_t)0x00ffULL)   8)
-   | ((val  (uint64_t)0xff00ULL)  24)
-   | ((val  (uint64_t)0x00ffULL)  40)
-   | ((val  (uint64_t)0xff00ULL)  56);
-}
-#  endif /* GNUC  GLIBC */
-#  define ntohll(n) bswap_64(n)
-#  define htonll(n) bswap_64(n)
-#else /* __BYTE_ORDER */
-#  error Can't define htonll or ntohll!
+#else
+# define ntohll(n) default_bswap64(n)
+# define htonll(n) default_bswap64(n)
 #endif
 
 #endif
-- 
1.8.4
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 0/5] fix up 'jk/pack-bitmap' branch

2013-11-07 Thread Ramsay Jones
Hi Jeff,

These patches fix various errors/warnings on the cygwin, MinGW and
msvc builds, provoked by the jk/pack-bitmap branch.

Note that this does not fix all problems on the msvc build; I have
a solution, but I don't like it. :-D  So, I'm going to try a different
fix. I had hoped to have done this by now, but ... (hopefully, sometime
this weekend).

Note that I have only tested the cygwin and MinGW builds by running
the t5310-pack-bitmaps.sh test, and only on a little-endian machine.
(Torsten has tested the first patch on a big-endian)

Note also, that these patches are build on top of the 'pu' branch
as of yesterday (pu @ 2b65d9ebc).

So, could you please squash these patches into the relevant commits
on your branch.

Thanks!

ATB,
Ramsay Jones

Ramsay Jones (5):
  compat/bswap.h: Fix build on cygwin, MinGW and msvc
  Makefile: Add object files in ewah/ to clean target
  khash.h: Spell the null pointer as NULL
  pack-objects: Limit visibility of 'indexed_commits' symbols
  ewah_bitmap.c: Fix printf format warnings on MinGW

 Makefile   |  5 +--
 builtin/pack-objects.c |  6 ++--
 compat/bswap.h | 97 +++---
 ewah/ewah_bitmap.c |  6 ++--
 khash.h|  2 +-
 5 files changed, 79 insertions(+), 37 deletions(-)

-- 
1.8.4
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 3/5] khash.h: Spell the null pointer as NULL

2013-11-07 Thread Ramsay Jones

Noticed by sparse. (Using plain integer as NULL pointer)

Signed-off-by: Ramsay Jones ram...@ramsay1.demon.co.uk
---
 khash.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/khash.h b/khash.h
index 0fdf39d..c4c1613 100644
--- a/khash.h
+++ b/khash.h
@@ -114,7 +114,7 @@ static const double __ac_HASH_UPPER = 0.77;
}   
\
SCOPE int kh_resize_##name(kh_##name##_t *h, khint_t new_n_buckets) \
{ /* This function uses 0.25*n_buckets bytes of working space instead 
of [sizeof(key_t+val_t)+.25]*n_buckets. */ \
-   khint32_t *new_flags = 0;   
\
+   khint32_t *new_flags = NULL;
\
khint_t j = 1;  
\
{   
\
kroundup32(new_n_buckets);  
\
-- 
1.8.4
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 5/5] ewah_bitmap.c: Fix printf format warnings on MinGW

2013-11-07 Thread Ramsay Jones

On MinGW, gcc complains as follows:

CC ewah/ewah_bitmap.o
ewah/ewah_bitmap.c: In function 'ewah_dump':
ewah/ewah_bitmap.c:389: warning: unknown conversion type \
character 'z' in format
ewah/ewah_bitmap.c:389: warning: unknown conversion type \
character 'z' in format
ewah/ewah_bitmap.c:389: warning: too many arguments for format
ewah/ewah_bitmap.c:392: warning: unknown conversion type \
character 'l' in format
ewah/ewah_bitmap.c:392: warning: too many arguments for format

In order to suppress the warnings, use the PRIuMAX and PRIx64 macros
from the inttypes.h header file.

Signed-off-by: Ramsay Jones ram...@ramsay1.demon.co.uk
---
 ewah/ewah_bitmap.c | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/ewah/ewah_bitmap.c b/ewah/ewah_bitmap.c
index 625f5a6..1e363b9 100644
--- a/ewah/ewah_bitmap.c
+++ b/ewah/ewah_bitmap.c
@@ -22,6 +22,7 @@
 #include unistd.h
 #include string.h
 #include stdio.h
+#include inttypes.h
 
 #include ewok.h
 #include ewok_rlw.h
@@ -386,10 +387,11 @@ void ewah_iterator_init(struct ewah_iterator *it, struct 
ewah_bitmap *parent)
 void ewah_dump(struct ewah_bitmap *self)
 {
size_t i;
-   fprintf(stderr, %zu bits | %zu words | , self-bit_size, 
self-buffer_size);
+   fprintf(stderr, %PRIuMAX bits | %PRIuMAX words | ,
+   (uintmax_t)self-bit_size, (uintmax_t)self-buffer_size);
 
for (i = 0; i  self-buffer_size; ++i)
-   fprintf(stderr, %016llx , (unsigned long 
long)self-buffer[i]);
+   fprintf(stderr, %016PRIx64 , (unsigned long 
long)self-buffer[i]);
 
fprintf(stderr, \n);
 }
-- 
1.8.4
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 2/5] Makefile: Add object files in ewah/ to clean target

2013-11-07 Thread Ramsay Jones

Signed-off-by: Ramsay Jones ram...@ramsay1.demon.co.uk
---
 Makefile | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/Makefile b/Makefile
index 07b0626..1950858 100644
--- a/Makefile
+++ b/Makefile
@@ -2484,8 +2484,9 @@ profile-clean:
$(RM) $(addsuffix *.gcno,$(addprefix $(PROFILE_DIR)/, $(object_dirs)))
 
 clean: profile-clean coverage-clean
-   $(RM) *.o *.res block-sha1/*.o ppc/*.o compat/*.o compat/*/*.o 
xdiff/*.o vcs-svn/*.o \
-   builtin/*.o $(LIB_FILE) $(XDIFF_LIB) $(VCSSVN_LIB)
+   $(RM) *.o *.res block-sha1/*.o ppc/*.o compat/*.o compat/*/*.o
+   $(RM) xdiff/*.o vcs-svn/*.o ewah/*.o builtin/*.o
+   $(RM) $(LIB_FILE) $(XDIFF_LIB) $(VCSSVN_LIB)
$(RM) $(ALL_PROGRAMS) $(SCRIPT_LIB) $(BUILT_INS) git$X
$(RM) $(TEST_PROGRAMS) $(NO_INSTALL)
$(RM) -r bin-wrappers $(dep_dirs)
-- 
1.8.4
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 4/5] pack-objects: Limit visibility of 'indexed_commits' symbols

2013-11-07 Thread Ramsay Jones

Noticed by sparse. (symbol '...' was not declared. Should it be
static?)

Signed-off-by: Ramsay Jones ram...@ramsay1.demon.co.uk
---
 builtin/pack-objects.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/builtin/pack-objects.c b/builtin/pack-objects.c
index 423e85a..161bfc2 100644
--- a/builtin/pack-objects.c
+++ b/builtin/pack-objects.c
@@ -85,9 +85,9 @@ static uint32_t reused, reused_delta;
 /*
  * Indexed commits
  */
-struct commit **indexed_commits;
-unsigned int indexed_commits_nr;
-unsigned int indexed_commits_alloc;
+static struct commit **indexed_commits;
+static unsigned int indexed_commits_nr;
+static unsigned int indexed_commits_alloc;
 
 static void index_commit_for_bitmap(struct commit *commit)
 {
-- 
1.8.4
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 0/5] fix up 'jk/pack-bitmap' branch

2013-11-07 Thread Jeff King
On Thu, Nov 07, 2013 at 09:58:02PM +, Ramsay Jones wrote:

 These patches fix various errors/warnings on the cygwin, MinGW and
 msvc builds, provoked by the jk/pack-bitmap branch.

Thanks. Your timing is impeccable, as I was just sitting down to
finalize the next re-roll. I'll add these in.

-Peff
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v4 01/14] submodule: don't access the .gitmodules cache entry after removing it

2013-11-07 Thread Heiko Voigt

Hi,

it looks like there is a From: Jens ... line missing on top of this patch.

Am 07.11.2013 15:33, schrieb Karsten Blees:

Commit 5fee995244e introduced the stage_updated_gitmodules() function to
add submodule configuration updates to the index. It assumed that even
after calling remove_cache_entry_at() the same cache entry would still be
valid. This was true in the old days, as cache entries could never be
freed, but that is not so sure in the present as there is ongoing work to
free removed cache entries, which makes this code segfault.

Fix that by calling add_file_to_cache() instead of open coding it. Also
remove the could not find .gitmodules in index warning, as that won't
happen in regular use cases (and by then just silently adding it to the
index we do the right thing).

Thanks-to: Karsten Blees karsten.bl...@gmail.com
Signed-off-by: Jens Lehmann jens.lehm...@web.de
Signed-off-by: Junio C Hamano gits...@pobox.com


Cheers Heiko
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 2/2] gitignore.txt: clarify recursive nature of excluded directories

2013-11-07 Thread Junio C Hamano
Thanks; will queue.
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 5/5] ewah_bitmap.c: Fix printf format warnings on MinGW

2013-11-07 Thread Junio C Hamano
Ramsay Jones ram...@ramsay1.demon.co.uk writes:

 On MinGW, gcc complains as follows:

 CC ewah/ewah_bitmap.o
 ewah/ewah_bitmap.c: In function 'ewah_dump':
 ewah/ewah_bitmap.c:389: warning: unknown conversion type \
 character 'z' in format
 ewah/ewah_bitmap.c:389: warning: unknown conversion type \
 character 'z' in format
 ewah/ewah_bitmap.c:389: warning: too many arguments for format
 ewah/ewah_bitmap.c:392: warning: unknown conversion type \
 character 'l' in format
 ewah/ewah_bitmap.c:392: warning: too many arguments for format

 In order to suppress the warnings, use the PRIuMAX and PRIx64 macros
 from the inttypes.h header file.

Good; it is in line with 28bd70d8 (unbreak and eliminate
NO_C99_FORMAT, 2011-03-16) and 3efb1f34 (Check for PRIuMAX rather
than NO_C99_FORMAT in fast-import.c., 2007-02-20).

Thanks.


 Signed-off-by: Ramsay Jones ram...@ramsay1.demon.co.uk
 ---
  ewah/ewah_bitmap.c | 6 --
  1 file changed, 4 insertions(+), 2 deletions(-)

 diff --git a/ewah/ewah_bitmap.c b/ewah/ewah_bitmap.c
 index 625f5a6..1e363b9 100644
 --- a/ewah/ewah_bitmap.c
 +++ b/ewah/ewah_bitmap.c
 @@ -22,6 +22,7 @@
  #include unistd.h
  #include string.h
  #include stdio.h
 +#include inttypes.h
  
  #include ewok.h
  #include ewok_rlw.h
 @@ -386,10 +387,11 @@ void ewah_iterator_init(struct ewah_iterator *it, 
 struct ewah_bitmap *parent)
  void ewah_dump(struct ewah_bitmap *self)
  {
   size_t i;
 - fprintf(stderr, %zu bits | %zu words | , self-bit_size, 
 self-buffer_size);
 + fprintf(stderr, %PRIuMAX bits | %PRIuMAX words | ,
 + (uintmax_t)self-bit_size, (uintmax_t)self-buffer_size);
  
   for (i = 0; i  self-buffer_size; ++i)
 - fprintf(stderr, %016llx , (unsigned long 
 long)self-buffer[i]);
 + fprintf(stderr, %016PRIx64 , (unsigned long 
 long)self-buffer[i]);
  
   fprintf(stderr, \n);
  }
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] checkout: most of the time we have good leading directories

2013-11-07 Thread Junio C Hamano
When git checkout wants to create a path, e.g. a/b/c/d/e, after
seeing if the entire thing already exists (in which case we check if
that is up-to-date and do not bother to check it out, or we unlink
and recreate it), we validate that the leading directory path is
without funny symlinks by seeing a/, a/b/, a/b/c/ and then a/b/c/d/
are all without funny symlinks, by calling has_dirs_only_path() in
this order.

When we are checking out many files (imagine: initial checkout),
however, it is likely that an earlier checkout would have already
made sure that the leading directory a/b/c/d/ is in good order; by
first checking the whole path a/b/c/d/ first, we can often bypass
calls to has_dirs_only_path() for leading part.

This cuts down the number of calls to has_dirs_only_path() for
checking out Linux kernel sources afresh from 190k down to 98k.

Signed-off-by: Junio C Hamano gits...@pobox.com
---

 * Just a random experimental change I was playing with today,
   looking for low hanging fruits before having to thread the entire
   checkout codepath.

 entry.c | 12 ++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/entry.c b/entry.c
index 7b7aa81..e2c0ac6 100644
--- a/entry.c
+++ b/entry.c
@@ -6,9 +6,17 @@
 static void create_directories(const char *path, int path_len,
   const struct checkout *state)
 {
-   char *buf = xmalloc(path_len + 1);
-   int len = 0;
+   char *buf;
+   int len;
+
+   for (len = path_len - 1; 0 = len; len--)
+   if (path[len] == '/')
+   break;
+   if (has_dirs_only_path(path, len, state-base_dir_len))
+   return; /* ok, we have the whole leading directory */
 
+   buf = xmalloc(path_len + 1);
+   len = 0;
while (len  path_len) {
do {
buf[len] = path[len];
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 1/5] compat/bswap.h: Fix build on cygwin, MinGW and msvc

2013-11-07 Thread SZEDER Gábor
Hi,

On Thu, Nov 07, 2013 at 09:59:38PM +, Ramsay Jones wrote:
 +static inline uint64_t default_bswap64(uint64_t val)
 +{
 + return (((val  (uint64_t)0x00ffULL)  56) |
 + ((val  (uint64_t)0xff00ULL)  40) |
 + ((val  (uint64_t)0x00ffULL)  24) |
 + ((val  (uint64_t)0xff00ULL)   8) |
 + ((val  (uint64_t)0x00ffULL)   8) |
 + ((val  (uint64_t)0xff00ULL)  24) |
 + ((val  (uint64_t)0x00ffULL)  40) |
 + ((val  (uint64_t)0xff00ULL)  56));
 +}

This got me thinking.
To swap 8 bytes this function performs 8 bitwise shifts, 8 bitwise
ANDs and 7 bitwise ORs plus uses 8 64bit constants.  We could do
better than that:

static inline uint64_t hacked_bswap64(uint64_t val)
{
uint64_t tmp = val  32 | val  32;
return (((tmp  (uint64_t)0xff00ff00ULL)  24) |
((tmp  (uint64_t)0x00ff00ffULL)   8) |
((tmp  (uint64_t)0xff00ff00ULL)   8) |
((tmp  (uint64_t)0x00ff00ffULL)  24));
}

This performs only 6 shifts, 4 ANDs, 4 ORs and uses 4 64bit constants.

bswap64ing 10 64bit ints with default_bswap64() compiled
with -O2 takes:

  real0m1.808s
  user0m1.796s
  sys 0m0.000s

The same with hacked_bswap64():

  real0m0.823s
  user0m0.816s
  sys 0m0.000s

I doubt that in normal usage git would spend enough time bswap64ing to
make this noticeable, but it was a fun micro-optimization on a wet
Thursday evening nevertheless :)

Best,
Gábor

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 0/5] fix up 'jk/pack-bitmap' branch

2013-11-07 Thread Vicent Martí
Thank you Ramsay, all the patches look OK to me.

On Thu, Nov 7, 2013 at 11:19 PM, Jeff King p...@peff.net wrote:
 On Thu, Nov 07, 2013 at 09:58:02PM +, Ramsay Jones wrote:

 These patches fix various errors/warnings on the cygwin, MinGW and
 msvc builds, provoked by the jk/pack-bitmap branch.

 Thanks. Your timing is impeccable, as I was just sitting down to
 finalize the next re-roll. I'll add these in.

 -Peff
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


вне зубрежки и нуднейших занятий

2013-11-07 Thread alfedorov71
Обратить свою биографию помногообразнее, воспылать замечательнейшим делом. 
Расширить круг общения. Применяются засекреченные экспресс-методы. Убыстренное 
обучение. Экспресс-курс для делающих первые щаги а так же углублённых. 
Приподнять личную цену на рынке работы. Вы сможете говорить по британски 
исключительно уже после первого урока. Веб: http://goo.gl/K9HOU8 .
N▀╖╡ФЛr╦⌡yЗХ ьb╡X╛╤г╖vь^√)ч╨{.nг+┴╥═┼ь╖╤⌡║э╗}╘·╡ф═zзj:+v┴╗╬╚▒ЙГzZ+─й+zfё╒╥h 
┬╖~├╜├шiЪШЮz╧╝w╔╒╦?≥╗Х╜з╒)ъ╒f