summaryrefslogtreecommitdiff
path: root/rerere.c
AgeCommit message (Collapse)AuthorFilesLines
2022-02-02ll-merge: make callers responsible for showing warningsLibravatar Elijah Newren1-4/+5
Since some callers may want to send warning messages to somewhere other than stdout/stderr, stop printing "warning: Cannot merge binary files" from ll-merge and instead modify the return status of ll_merge() to indicate when a merge of binary files has occurred. Message printing probably does not belong in a "low-level merge" anyway. This commit continues printing the message as-is, just from the callers instead of within ll_merge(). Future changes will start handling the message differently in the merge-ort codepath. There was one special case here: the callers in rerere.c do NOT check for and print such a message; since those code paths explicitly skip over binary files, there is no reason to check for a return status of LL_MERGE_BINARY_CONFLICT or print the related message. Note that my methodology included first modifying ll_merge() to return a struct, so that the compiler would catch all the callers for me and ensure I had modified all of them. After modifying all of them, I then changed the struct to an enum. Signed-off-by: Elijah Newren <newren@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2021-05-13dir: introduce readdir_skip_dot_and_dotdot() helperLibravatar Elijah Newren1-3/+1
Many places in the code were doing while ((d = readdir(dir)) != NULL) { if (is_dot_or_dotdot(d->d_name)) continue; ...process d... } Introduce a readdir_skip_dot_and_dotdot() helper to make that a one-liner: while ((d = readdir_skip_dot_and_dotdot(dir)) != NULL) { ...process d... } This helper particularly simplifies checks for empty directories. Also use this helper in read_cached_dir() so that our statistics are consistent across platforms. (In other words, read_cached_dir() should have been using is_dot_or_dotdot() and skipping such entries, but did not and left it to treat_path() to detect and mark such entries as path_none.) Signed-off-by: Elijah Newren <newren@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2021-01-28rerere: use strmap to store rerere directoriesLibravatar Jeff King1-39/+23
We store a struct for each directory we access under .git/rr-cache. The structs are kept in an array sorted by the binary hash associated with their name (and we do lookups with a binary search). This works OK, but there are a few small downsides: - the amount of code isn't huge, but it's more than we'd need using one of our other stock data structures - the insertion into a sorted array is quadratic (though in practice it's unlikely anybody has enough conflicts for this to matter) - it's intimately tied to the representation of an object hash. This isn't a big deal, as the conflict ids we generate use the same hash, but it produces a few awkward bits (e.g., we are the only user of hash_pos() that is not using object_id). Let's instead just treat the directory names as strings, and store them in a strmap. This is less code, and removes the use of hash_pos(). Insertion is now non-quadratic, though we probably use a bit more memory. Besides the hash table overhead, and storing hex bytes instead of a binary hash, we actually store each name twice. Other code expects to access the name of a rerere_dir struct from the struct itself, so we need a copy there. But strmap keeps its own copy of the name, as well. Using a bare hashmap instead of strmap means we could use the name for both, but at the cost of extra code (e.g., our own comparison function). Likewise, strmap has a feature to use a pointer to the in-struct name at the cost of a little extra code. I didn't do either here, as simple code seemed more important than squeezing out a few bytes of efficiency. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2021-01-28rerere: tighten rr-cache dirname checkLibravatar Jeff King1-2/+3
We check only that get_sha1_hex() doesn't complain, which means we'd match an all-hex name with trailing cruft after it. This probably doesn't matter much in practice, since there shouldn't be anything else in the rr-cache directory, but it could possibly cause us to mix up sha1 and sha256 entries (which also shouldn't be intermingled, but could be leftovers from a repository conversion). Note that "get_sha1_hex()" is a confusing historical name. It is actually using the_hash_algo, so it would be sha256 in a sha256 repo. We'll switch to using parse_oid_hex(), because that conveniently advances our pointer. But it also gets rid of the sha1 name. Arguably it's a little funny to use "object_id" here for something that isn't actually naming an object, but it's unlikely to be a problem (and is contained in a single function). Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2021-01-28rerere: check dirname format while iterating rr_cache directoryLibravatar Jeff King1-3/+11
In rerere_gc(), we walk over the .git/rr_cache directory and create a struct for each entry we find. We feed any name we get from readdir() to find_rerere_dir(), which then calls get_sha1_hex() on it (since we use the binary hash as a lookup key). If that fails (i.e., the directory name is not what we expected), it returns NULL. But the comment in find_rerere_dir() says "BUG". It _would_ be a bug for the call from new_rerere_id_hex(), the only other code path, to fail here; it's generating the hex internally. But the call in rerere_gc() is using it say "is this a plausible directory name". Let's instead have rerere_gc() do its own "is this plausible" check. That has two benefits: - we can now reliably BUG() inside find_rerere_dir(), which would catch bugs in the other code path (and we now will never return NULL from the function, which makes it easier to see that a rerere_id struct will always have a non-NULL "collection" field). - it makes the use of the binary hash an implementation detail of find_rerere_dir(), not known by callers. That will free us up to change it in a future patch. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2021-01-04hash-lookup: rename from sha1-lookupLibravatar Martin Ågren1-1/+1
Change all remnants of "sha1" in hash-lookup.c and .h and rename them to reflect that we're not just able to handle SHA-1 these days. Signed-off-by: Martin Ågren <martin.agren@gmail.com> Reviewed-by: Derrick Stolee <dstolee@microsoft.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2021-01-04sha1-lookup: rename `sha1_pos()` as `hash_pos()`Libravatar Martin Ågren1-1/+1
Rename this function to reflect that we're not just able to handle SHA-1 these days. There are a few instances of "sha1" left in sha1-lookup.[ch] after this, but those will be addressed in the next commit. Signed-off-by: Martin Ågren <martin.agren@gmail.com> Reviewed-by: Derrick Stolee <dstolee@microsoft.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2019-11-10Fix spelling errors in code commentsLibravatar Elijah Newren1-1/+1
Reported-by: Jens Schleusener <Jens.Schleusener@fossies.org> Signed-off-by: Elijah Newren <newren@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2019-08-19rerere: replace sha1_to_hexLibravatar brian m. carlson1-4/+4
Replace the uses of sha1_to_hex in this function with hash_to_hex to allow the use of SHA-256 as well. Rename a variable since it is no longer limited to SHA-1. Signed-off-by: brian m. carlson <sandals@crustytoothpaste.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2019-01-14read-cache.c: kill read_index()Libravatar Nguyễn Thái Ngọc Duy1-3/+3
read_index() shares the same problem as hold_locked_index(): it assumes $GIT_DIR/index. Move all call sites to repo_read_index() instead. read_index_preload() and read_index_unmerged() are also killed as a consequence. Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2019-01-14repository.c: replace hold_locked_index() with repo_hold_locked_index()Libravatar Nguyễn Thái Ngọc Duy1-1/+1
hold_locked_index() assumes the index path at $GIT_DIR/index. This is not good for places that take an arbitrary index_state instead of the_index, which is basically everywhere except builtin/. Replace it with repo_hold_locked_index(). hold_locked_index() remains as a wrapper around repo_hold_locked_index() to reduce changes in builtin/ Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-11-12rerere.c: remove the_repository referencesLibravatar Nguyễn Thái Ngọc Duy1-13/+13
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-10-30Merge branch 'bc/hash-transition-part-15'Libravatar Junio C Hamano1-41/+44
More codepaths are moving away from hardcoded hash sizes. * bc/hash-transition-part-15: rerere: convert to use the_hash_algo submodule: make zero-oid comparison hash function agnostic apply: rename new_sha1_prefix and old_sha1_prefix apply: replace hard-coded constants tag: express constant in terms of the_hash_algo transport: use parse_oid_hex instead of a constant upload-pack: express constants in terms of the_hash_algo refs/packed-backend: express constants using the_hash_algo packfile: express constants in terms of the_hash_algo pack-revindex: express constants in terms of the_hash_algo builtin/fetch-pack: remove constants with parse_oid_hex builtin/mktree: remove hard-coded constant builtin/repack: replace hard-coded constants pack-bitmap-write: use GIT_MAX_RAWSZ for allocation object_id.cocci: match only expressions of type 'struct object_id'
2018-10-19Merge branch 'nd/the-index'Libravatar Junio C Hamano1-55/+66
Various codepaths in the core-ish part learn to work on an arbitrary in-core index structure, not necessarily the default instance "the_index". * nd/the-index: (23 commits) revision.c: reduce implicit dependency the_repository revision.c: remove implicit dependency on the_index ws.c: remove implicit dependency on the_index tree-diff.c: remove implicit dependency on the_index submodule.c: remove implicit dependency on the_index line-range.c: remove implicit dependency on the_index userdiff.c: remove implicit dependency on the_index rerere.c: remove implicit dependency on the_index sha1-file.c: remove implicit dependency on the_index patch-ids.c: remove implicit dependency on the_index merge.c: remove implicit dependency on the_index merge-blobs.c: remove implicit dependency on the_index ll-merge.c: remove implicit dependency on the_index diff-lib.c: remove implicit dependency on the_index read-cache.c: remove implicit dependency on the_index diff.c: remove implicit dependency on the_index grep.c: remove implicit dependency on the_index diff.c: remove the_index dependency in textconv() functions blame.c: rename "repo" argument to "r" combine-diff.c: remove implicit dependency on the_index ...
2018-10-15rerere: convert to use the_hash_algoLibravatar brian m. carlson1-39/+42
Since this data is stored in the .git directory, it makes sense for us to use the same hash algorithm for it as for everything else. Convert the remaining uses of SHA-1 to use the_hash_algo. Use GIT_MAX_RAWSZ for allocations. Rename various struct members, local variables, and a function to be named "hash" instead of "sha1". Signed-off-by: brian m. carlson <sandals@crustytoothpaste.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-09-24Merge branch 'en/rerere-multi-stage-1-fix'Libravatar Junio C Hamano1-1/+1
A corner case bugfix in "git rerere" code. * en/rerere-multi-stage-1-fix: rerere: avoid buffer overrun t4200: demonstrate rerere segfault on specially crafted merge
2018-09-21rerere.c: remove implicit dependency on the_indexLibravatar Nguyễn Thái Ngọc Duy1-55/+64
The reason rerere(), rerere_forget() and rerere_remaining() take a struct repository instead of struct index_state is not obvious from the patch: Deep in update_paths() and find_conflict(), hold_locked_index() and read_index() are called. These functions assumes the index path at $GIT_DIR/index which is not always true when you take an arbitrary index state. Taking a repository will allow us to point to the right index path later when we replace them with repo_ versions. Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-09-21ll-merge.c: remove implicit dependency on the_indexLibravatar Nguyễn Thái Ngọc Duy1-4/+6
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-09-17Merge branch 'tg/rerere'Libravatar Junio C Hamano1-127/+116
Fixes to "git rerere" corner cases, especially when conflict markers cannot be parsed in the file. * tg/rerere: rerere: recalculate conflict ID when unresolved conflict is committed rerere: teach rerere to handle nested conflicts rerere: return strbuf from handle path rerere: factor out handle_conflict function rerere: only return whether a path has conflicts or not rerere: fix crash with files rerere can't handle rerere: add documentation for conflict normalization rerere: mark strings for translation rerere: wrap paths in output in sq rerere: lowercase error messages rerere: unify error messages when read_cache fails
2018-09-11rerere: avoid buffer overrunLibravatar Elijah Newren1-1/+1
check_one_conflict() compares `i` to `active_nr` in two places to avoid buffer overruns, but left out an important third location. The code did used to have a check here comparing i to active_nr, back before commit fb70a06da2f1 ("rerere: fix an off-by-one non-bug", 2015-06-28), however the code at the time used an 'if' rather than a 'while' meaning back then that this loop could not have read past the end of the array, making the check unnecessary and it was removed. Unfortunately, in commit 5eda906b2873 ("rerere: handle conflicts with multiple stage #1 entries", 2015-07-24), the 'if' was changed to a 'while' and the check comparing i and active_nr was not re-instated, leading to this problem. Signed-off-by: Elijah Newren <newren@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-08-13dir.c: remove an implicit dependency on the_index in pathspec codeLibravatar Nguyễn Thái Ngọc Duy1-1/+1
Make the match_patchspec API and friends take an index_state instead of assuming the_index in dir.c. All external call sites are converted blindly to keep the patch simple and retain current behavior. Individual call sites may receive further updates to use the right index instead of the_index. Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-08-06rerere: recalculate conflict ID when unresolved conflict is committedLibravatar Thomas Gummerer1-4/+3
Currently when a user doesn't resolve a conflict, commits the results, and does an operation which creates another conflict, rerere will use the ID of the previously unresolved conflict for the new conflict. This is because the conflict is kept in the MERGE_RR file, which 'rerere' reads every time it is invoked. After the new conflict is solved, rerere will record the resolution with the ID of the old conflict. So in order to replay the conflict, both merges would have to be re-done, instead of just the last one, in order for rerere to be able to automatically resolve the conflict. Instead of that, assign a new conflict ID if there are still conflicts in a file and the file had conflicts at a previous step. This ID matches the conflict we actually resolved at the corresponding step. Note that there are no backwards compatibility worries here, as rerere would have failed to even normalize the conflict before this patch series. Signed-off-by: Thomas Gummerer <t.gummerer@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-08-06rerere: teach rerere to handle nested conflictsLibravatar Thomas Gummerer1-2/+8
Currently rerere can't handle nested conflicts and will error out when it encounters such conflicts. Do that by recursively calling the 'handle_conflict' function to normalize the conflict. Note that a conflict like this would only be produced if a user commits a file with conflict markers, and gets a conflict including that in a susbsequent operation. The conflict ID calculation here deserves some explanation: As we are using the same handle_conflict function, the nested conflict is normalized the same way as for non-nested conflicts, which means the ancestor in the diff3 case is stripped out, and the parts of the conflict are ordered alphabetically. The conflict ID is however is only calculated in the top level handle_conflict call, so it will include the markers that 'rerere' adds to the output. e.g. say there's the following conflict: <<<<<<< HEAD 1 ======= <<<<<<< HEAD 3 ======= 2 >>>>>>> branch-2 >>>>>>> branch-3~ it would be recorde as follows in the preimage: <<<<<<< 1 ======= <<<<<<< 2 ======= 3 >>>>>>> >>>>>>> and the conflict ID would be calculated as sha1(1<NUL><<<<<<< 2 ======= 3 >>>>>>><NUL>) Stripping out vs. leaving the conflict markers in place in the inner conflict should have no practical impact, but it simplifies the implementation. Signed-off-by: Thomas Gummerer <t.gummerer@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-08-06rerere: return strbuf from handle pathLibravatar Thomas Gummerer1-40/+18
Currently we write the conflict to disk directly in the handle_path function. To make it re-usable for nested conflicts, instead of writing the conflict out directly, store it in a strbuf and let the caller write it out. This does mean some slight increase in memory usage, however that increase is limited to the size of the largest conflict we've currently processed. We already keep one copy of the conflict in memory, and it shouldn't be too large, so the increase in memory usage seems acceptable. As a bonus this lets us get replace the rerere_io_putconflict function with a trivial two line function. Signed-off-by: Thomas Gummerer <t.gummerer@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-08-06rerere: factor out handle_conflict functionLibravatar Thomas Gummerer1-40/+47
Factor out the handle_conflict function, which handles a single conflict in a path. This is in preparation for a subsequent commit, where this function will be re-used. Note that this does change the behaviour of 'git rerere' slightly. Where previously we'd consider all files where an unmatched conflict marker is found as invalid, we now only consider files invalid when the "ours" conflict marker ("<<<<<<< <text>") is unmatched, not when other conflict markers (e.g. "=======") is unmatched. Signed-off-by: Thomas Gummerer <t.gummerer@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-08-06rerere: only return whether a path has conflicts or notLibravatar Thomas Gummerer1-11/+12
We currently return the exact number of conflict hunks a certain path has from the 'handle_paths' function. However all of its callers only care whether there are conflicts or not or if there is an error. Return only that information, and document that only that information is returned. This will simplify the code in the subsequent steps. Signed-off-by: Thomas Gummerer <t.gummerer@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-08-06rerere: fix crash with files rerere can't handleLibravatar Thomas Gummerer1-5/+7
Currently when a user does a conflict resolution and ends it (in any way that calls 'git rerere' again) with a file 'rerere' can't handle, subsequent rerere operations that are interested in that path, such as 'rerere clear' or 'rerere forget <path>' will fail, or even worse in the case of 'rerere clear' segfault. Such states include nested conflicts, or a conflict marker that doesn't have any match. This is because 'git rerere' calculates a conflict file and writes it to the MERGE_RR file. When the user then changes the file in any way rerere can't handle, and then calls 'git rerere' on it again to record the conflict resolution, the handle_file function fails, and removes the 'preimage' file in the rr-cache in the process, while leaving the ID in the MERGE_RR file. Now when 'rerere clear' is run, it reads the ID from the MERGE_RR file, however the 'fit_variant' function for the ID is never called as the 'preimage' file does not exist anymore. This means 'collection->status' in 'has_rerere_resolution' is NULL, and the command will crash. To fix this, remove the rerere ID from the MERGE_RR file in the case when we can't handle it, just after the 'preimage' file was removed and remove the corresponding variant from .git/rr-cache/. Removing it unconditionally is fine here, because if the user would have resolved the conflict and ran rerere, the entry would no longer be in the MERGE_RR file, so we wouldn't have this problem in the first place, while if the conflict was not resolved. Currently there is nothing left in this folder, as the 'preimage' was already deleted by the 'handle_file' function, so 'remove_variant' is a no-op. Still call the function, to make sure we clean everything up, in case we add some other files corresponding to a variant in the future. Note that other variants that have the same conflict ID will not be touched. Signed-off-by: Thomas Gummerer <t.gummerer@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-08-06rerere: add documentation for conflict normalizationLibravatar Thomas Gummerer1-4/+0
Add some documentation for the logic behind the conflict normalization in rerere. Helped-by: Junio C Hamano <gitster@pobox.com> Signed-off-by: Thomas Gummerer <t.gummerer@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-08-06rerere: mark strings for translationLibravatar Thomas Gummerer1-34/+34
'git rerere' is considered a porcelain command and as such its output should be translated. Its functionality is also only enabled through a config setting, so scripts really shouldn't rely on the output either way. Signed-off-by: Thomas Gummerer <t.gummerer@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-07-18Merge branch 'sb/object-store-grafts'Libravatar Junio C Hamano1-3/+5
The conversion to pass "the_repository" and then "a_repository" throughout the object access API continues. * sb/object-store-grafts: commit: allow lookup_commit_graft to handle arbitrary repositories commit: allow prepare_commit_graft to handle arbitrary repositories shallow: migrate shallow information into the object parser path.c: migrate global git_path_* to take a repository argument cache: convert get_graft_file to handle arbitrary repositories commit: convert read_graft_file to handle arbitrary repositories commit: convert register_commit_graft to handle arbitrary repositories commit: convert commit_graft_pos() to handle arbitrary repositories shallow: add repository argument to is_repository_shallow shallow: add repository argument to check_shallow_file_for_update shallow: add repository argument to register_shallow shallow: add repository argument to set_alternate_shallow_file commit: add repository argument to lookup_commit_graft commit: add repository argument to prepare_commit_graft commit: add repository argument to read_graft_file commit: add repository argument to register_commit_graft commit: add repository argument to commit_graft_pos object: move grafts to object parser object-store: move object access functions to object-store.h
2018-07-16rerere: wrap paths in output in sqLibravatar Thomas Gummerer1-13/+13
It looks like most paths in the output in the git codebase are wrapped in single quotes. Standardize on that in rerere as well. Apart from being more consistent, this also makes some of the strings match strings that are already translated in other parts of the codebase, thus reducing the work for translators, when the strings are marked for translation in a subsequent commit. Signed-off-by: Thomas Gummerer <t.gummerer@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-07-16rerere: lowercase error messagesLibravatar Thomas Gummerer1-12/+12
Documentation/CodingGuidelines mentions that error messages should be lowercase. Prior to marking them for translation follow that pattern in rerere as well, so translators won't have to translate messages that don't conform to our guidelines. Signed-off-by: Thomas Gummerer <t.gummerer@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-07-16rerere: unify error messages when read_cache failsLibravatar Thomas Gummerer1-3/+3
We have multiple different variants of the error message we show to the user if 'read_cache' fails. The "Could not read index" variant we are using in 'rerere.c' is currently not used anywhere in translated form. As a subsequent commit will mark all output that comes from 'rerere.c' for translation, make the life of the translators a little bit easier by using a string that is used elsewhere, and marked for translation there, and thus most likely already translated. "index file corrupt" seems to be the most common error message we show when 'read_cache' fails, so use that here as well. Signed-off-by: Thomas Gummerer <t.gummerer@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-05-30Merge branch 'ma/lockfile-cleanup'Libravatar Junio C Hamano1-2/+1
Code clean-up to adjust to a more recent lockfile API convention that allows lockfile instances kept on the stack. * ma/lockfile-cleanup: lock_file: move static locks into functions lock_file: make function-local locks non-static refs.c: do not die if locking fails in `delete_pseudoref()` refs.c: do not die if locking fails in `write_pseudoref()` t/helper/test-write-cache: clean up lock-handling
2018-05-18path.c: migrate global git_path_* to take a repository argumentLibravatar Stefan Beller1-3/+4
Migrate all git_path_* functions that are defined in path.c to take a repository argument. Unlike other patches in this series, do not use the #define trick, as we rewrite the whole function, which is rather small. This doesn't migrate all the functions, as other builtins have their own local path functions defined using GIT_PATH_FUNC. So keep that macro around to serve the other locations. Signed-off-by: Stefan Beller <sbeller@google.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-05-16object-store: move object access functions to object-store.hLibravatar Stefan Beller1-0/+1
This should make these functions easier to find and cache.h less overwhelming to read. In particular, this moves: - read_object_file - oid_object_info - write_object_file As a result, most of the codebase needs to #include object-store.h. In this patch the #include is only added to files that would fail to compile otherwise. It would be better to #include wherever identifiers from the header are used. That can happen later when we have better tooling for it. Signed-off-by: Stefan Beller <sbeller@google.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-05-10lock_file: move static locks into functionsLibravatar Martin Ågren1-2/+1
Placing `struct lock_file`s on the stack used to be a bad idea, because the temp- and lockfile-machinery would keep a pointer into the struct. But after 076aa2cbd (tempfile: auto-allocate tempfiles on heap, 2017-09-05), we can safely have lockfiles on the stack. (This applies even if a user returns early, leaving a locked lock behind.) Each of these `struct lock_file`s is used from within a single function. Move them into the respective functions to make the scope clearer and drop the staticness. For good measure, I have inspected these sites and come to believe that they always release the lock, with the possible exception of bailing out using `die()` or `exit()` or by returning from a `cmd_foo()`. As pointed out by Jeff King, it would be bad if someone held on to a `struct lock_file *` for some reason. After some grepping, I agree with his findings: no-one appears to be doing that. After this commit, the remaining occurrences of "static struct lock_file" are locks that are used from within different functions. That is, they need to remain static. (Short of more intrusive changes like passing around pointers to non-static locks.) Signed-off-by: Martin Ågren <martin.agren@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-04-10Merge branch 'bc/object-id'Libravatar Junio C Hamano1-2/+2
Conversion from uchar[20] to struct object_id continues. * bc/object-id: (36 commits) convert: convert to struct object_id sha1_file: introduce a constant for max header length Convert lookup_replace_object to struct object_id sha1_file: convert read_sha1_file to struct object_id sha1_file: convert read_object_with_reference to object_id tree-walk: convert tree entry functions to object_id streaming: convert istream internals to struct object_id tree-walk: convert get_tree_entry_follow_symlinks internals to object_id builtin/notes: convert static functions to object_id builtin/fmt-merge-msg: convert remaining code to object_id sha1_file: convert sha1_object_info* to object_id Convert remaining callers of sha1_object_info_extended to object_id packfile: convert unpack_entry to struct object_id sha1_file: convert retry_bad_packed_offset to struct object_id sha1_file: convert assert_sha1_type to object_id builtin/mktree: convert to struct object_id streaming: convert open_istream to use struct object_id sha1_file: convert check_sha1_signature to struct object_id sha1_file: convert read_loose_object to use struct object_id builtin/index-pack: convert struct ref_delta_entry to object_id ...
2018-03-14sha1_file: convert read_sha1_file to struct object_idLibravatar brian m. carlson1-2/+2
Convert read_sha1_file to take a pointer to struct object_id and rename it read_object_file. Do the same for read_sha1_file_extended. Convert one use in grep.c to use the new function without any other code change, since the pointer being passed is a void pointer that is already initialized with a pointer to struct object_id. Update the declaration and definitions of the modified functions, and apply the following semantic patch to convert the remaining callers: @@ expression E1, E2, E3; @@ - read_sha1_file(E1.hash, E2, E3) + read_object_file(&E1, E2, E3) @@ expression E1, E2, E3; @@ - read_sha1_file(E1->hash, E2, E3) + read_object_file(E1, E2, E3) @@ expression E1, E2, E3, E4; @@ - read_sha1_file_extended(E1.hash, E2, E3, E4) + read_object_file_extended(&E1, E2, E3, E4) @@ expression E1, E2, E3, E4; @@ - read_sha1_file_extended(E1->hash, E2, E3, E4) + read_object_file_extended(E1, E2, E3, E4) Signed-off-by: brian m. carlson <sandals@crustytoothpaste.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-03-01write_locked_index(): add flag to avoid writing unchanged indexLibravatar Martin Ågren1-5/+3
We have several callers like if (active_cache_changed && write_locked_index(...)) handle_error(); rollback_lock_file(...); where the final rollback is needed because "!active_cache_changed" shortcuts the if-expression. There are also a few variants of this, including some if-else constructs that make it more clear when the explicit rollback is really needed. Teach `write_locked_index()` to take a new flag SKIP_IF_UNCHANGED and simplify the callers. Leave the most complicated of the callers (in builtin/update-index.c) unchanged. Rewriting it to use this new flag would end up duplicating logic. We could have made the new flag behave the other way round ("FORCE_WRITE"), but that could break existing users behind their backs. Let's take the more conservative approach. We can still migrate existing callers to use our new flag. Later we might even be able to flip the default, possibly without entirely ignoring the risk to in-flight or out-of-tree topics. Suggested-by: Jeff King <peff@peff.net> Signed-off-by: Martin Ågren <martin.agren@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-01-22Use MOVE_ARRAYLibravatar SZEDER Gábor1-2/+2
Use the helper macro MOVE_ARRAY to move arrays. This is shorter and safer, as it automatically infers the size of elements. Patch generated by Coccinelle and contrib/coccinelle/array.cocci in Travis CI's static analysis build job. Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-09-25Merge branch 'jk/write-in-full-fix'Libravatar Junio C Hamano1-1/+1
Many codepaths did not diagnose write failures correctly when disks go full, due to their misuse of write_in_full() helper function, which have been corrected. * jk/write-in-full-fix: read_pack_header: handle signed/unsigned comparison in read result config: flip return value of store_write_*() notes-merge: use ssize_t for write_in_full() return value pkt-line: check write_in_full() errors against "< 0" convert less-trivial versions of "write_in_full() != len" avoid "write_in_full(fd, buf, len) != len" pattern get-tar-commit-id: check write_in_full() return against 0 config: avoid "write_in_full(fd, buf, len) < len" pattern
2017-09-14avoid "write_in_full(fd, buf, len) != len" patternLibravatar Jeff King1-1/+1
The return value of write_in_full() is either "-1", or the requested number of bytes[1]. If we make a partial write before seeing an error, we still return -1, not a partial value. This goes back to f6aa66cb95 (write_in_full: really write in full or return error on disk full., 2007-01-11). So checking anything except "was the return value negative" is pointless. And there are a couple of reasons not to do so: 1. It can do a funny signed/unsigned comparison. If your "len" is signed (e.g., a size_t) then the compiler will promote the "-1" to its unsigned variant. This works out for "!= len" (unless you really were trying to write the maximum size_t bytes), but is a bug if you check "< len" (an example of which was fixed recently in config.c). We should avoid promoting the mental model that you need to check the length at all, so that new sites are not tempted to copy us. 2. Checking for a negative value is shorter to type, especially when the length is an expression. 3. Linus says so. In d34cf19b89 (Clean up write_in_full() users, 2007-01-11), right after the write_in_full() semantics were changed, he wrote: I really wish every "write_in_full()" user would just check against "<0" now, but this fixes the nasty and stupid ones. Appeals to authority aside, this makes it clear that writing it this way does not have an intentional benefit. It's a historical curiosity that we never bothered to clean up (and which was undoubtedly cargo-culted into new sites). So let's convert these obviously-correct cases (this includes write_str_in_full(), which is just a wrapper for write_in_full()). [1] A careful reader may notice there is one way that write_in_full() can return a different value. If we ask write() to write N bytes and get a return value that is _larger_ than N, we could return a larger total. But besides the fact that this would imply a totally broken version of write(), it would already invoke undefined behavior. Our internal remaining counter is an unsigned size_t, which means that subtracting too many byte will wrap it around to a very large number. So we'll instantly begin reading off the end of the buffer, trying to write gigabytes (or petabytes) of data. Signed-off-by: Jeff King <peff@peff.net> Reviewed-by: Jonathan Nieder <jrnieder@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-08-22rerere: allow approxidate in gc.rerereResolved/gc.rerereUnresolvedLibravatar Junio C Hamano1-12/+2
These two configuration variables are described in the documentation to take an expiry period expressed in the number of days: gc.rerereResolved:: Records of conflicted merge you resolved earlier are kept for this many days when 'git rerere gc' is run. The default is 60 days. gc.rerereUnresolved:: Records of conflicted merge you have not resolved are kept for this many days when 'git rerere gc' is run. The default is 15 days. There is no strong reason not to allow a more general "approxidate" expiry specification, e.g. "5.days.ago", or "never". Rename the config_get_expiry() helper introduced in the previous step to git_config_get_expiry_in_days() and move it to a more generic place, config.c, and use date.c::parse_expiry_date() to do so. Give it an ability to allow the caller to tell among three cases (i.e. there is no "gc.rerereResolved" config, there is and it is correctly parsed into the *expiry variable, and there was an error in parsing the given value). The current caller can work correctly without using the return value, though. In the future, we may find other variables that only allow an integer that specifies "this many days" or other unit of time, and when it happens we may need to drop "_days" suffix from the name of the function and instead pass the "scale" value as another parameter. But this will do for now. Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-08-22rerere: represent time duration in timestamp_t internallyLibravatar Junio C Hamano1-13/+23
The two configuration variables, gc.rerereResolved and gc.rerereUnresolved, are measured in days and are passed as such into the prune_one() helper function, which worked in time_t to see if an entry in the rerere database is past its expiry. Instead, have the caller turn the number of days into the expiry timestamp. Further, use timestamp_t instead of time_t. This will make it possible to extend the way the configuration variable is spelled by using date.c::parse_expiry_date() that gives the expiry timestamp in timestamp_t. Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-06-24Merge branch 'ab/free-and-null'Libravatar Junio C Hamano1-2/+1
A common pattern to free a piece of memory and assign NULL to the pointer that used to point at it has been replaced with a new FREE_AND_NULL() macro. * ab/free-and-null: *.[ch] refactoring: make use of the FREE_AND_NULL() macro coccinelle: make use of the "expression" FREE_AND_NULL() rule coccinelle: add a rule to make "expression" code use FREE_AND_NULL() coccinelle: make use of the "type" FREE_AND_NULL() rule coccinelle: add a rule to make "type" code use FREE_AND_NULL() git-compat-util: add a FREE_AND_NULL() wrapper around free(ptr); ptr = NULL
2017-06-24Merge branch 'bw/config-h'Libravatar Junio C Hamano1-0/+1
Fix configuration codepath to pay proper attention to commondir that is used in multi-worktree situation, and isolate config API into its own header file. * bw/config-h: config: don't implicitly use gitdir or commondir config: respect commondir setup: teach discover_git_directory to respect the commondir config: don't include config.h by default config: remove git_config_iter config: create config.h
2017-06-16*.[ch] refactoring: make use of the FREE_AND_NULL() macroLibravatar Ævar Arnfjörð Bjarmason1-2/+1
Replace occurrences of `free(ptr); ptr = NULL` which weren't caught by the coccinelle rule. These fall into two categories: - free/NULL assignments one after the other which coccinelle all put on one line, which is functionally equivalent code, but very ugly. - manually spotted occurrences where the NULL assignment isn't right after the free() call. Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-06-15config: don't include config.h by defaultLibravatar Brandon Williams1-0/+1
Stop including config.h by default in cache.h. Instead only include config.h in those files which require use of the config system. Signed-off-by: Brandon Williams <bmwill@google.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-05-26rerere.c: move error_errno() closer to the source system callLibravatar Nguyễn Thái Ngọc Duy1-1/+2
We are supposed to report errno from fopen(). fclose() between fopen() and the report function could either change errno or reset it. Signed-off-by: Junio C Hamano <gitster@pobox.com>