Merge tag 'v2.23.0-rc2' of git://git.kernel.org/pub/scm/git/git

Git 2.23-rc2

* tag 'v2.23.0-rc2' of git://git.kernel.org/pub/scm/git/git: (63 commits)
  Git 2.23-rc2
  t0000: reword comments for "local" test
  t: decrease nesting in test_oid_to_path
  sha1-file: release strbuf after use
  test-dir-iterator: use path argument directly
  dir-iterator: release strbuf after use
  commit-graph: release strbufs after use
  l10n: reformat some localized strings for v2.23.0
  merge-recursive: avoid directory rename detection in recursive case
  commit-graph: fix bug around octopus merges
  restore: fix typo in docs
  doc: typo: s/can not/cannot/ and s/is does/does/
  Git 2.23-rc1
  log: really flip the --mailmap default
  RelNotes/2.23.0: fix a few typos and other minor issues
  RelNotes/2.21.1: typofix
  log: flip the --mailmap default unconditionally
  config: work around bug with includeif:onbranch and early config
  A few more last-minute fixes
  repack: simplify handling of auto-bitmaps and .keep files
  ...
This commit is contained in:
Jiang Xin
2019-08-10 20:11:17 +08:00
59 changed files with 1035 additions and 390 deletions

8
.gitignore vendored
View File

@ -231,6 +231,10 @@
*.ipdb *.ipdb
*.dll *.dll
.vs/ .vs/
/Debug/ *.manifest
/Release/ Debug/
Release/
/UpgradeLog*.htm
/git.VC.VC.opendb
/git.VC.db
*.dSYM *.dSYM

View File

@ -94,7 +94,7 @@ Fixes since v2.22
* The configuration variable rebase.rescheduleFailedExec should be * The configuration variable rebase.rescheduleFailedExec should be
effective only while running an interactive rebase and should not effective only while running an interactive rebase and should not
affect anything when running an non-interactive one, which was not affect anything when running a non-interactive one, which was not
the case. This has been corrected. the case. This has been corrected.
* "git submodule foreach" did not protect command line options passed * "git submodule foreach" did not protect command line options passed

View File

@ -10,6 +10,9 @@ Backward compatibility note
prerequisite patches in an unstable way, which has been updated to prerequisite patches in an unstable way, which has been updated to
compute in a way that is compatible with "git patch-id --stable". compute in a way that is compatible with "git patch-id --stable".
* The "git log" command by default behaves as if the --mailmap option
was given.
UI, Workflows & Features UI, Workflows & Features
@ -52,7 +55,7 @@ UI, Workflows & Features
* "git fetch" and "git pull" reports when a fetch results in * "git fetch" and "git pull" reports when a fetch results in
non-fast-forward updates to let the user notice unusual situation. non-fast-forward updates to let the user notice unusual situation.
The commands learned "--no-shown-forced-updates" option to disable The commands learned "--no-show-forced-updates" option to disable
this safety feature. this safety feature.
* Two new commands "git switch" and "git restore" are introduced to * Two new commands "git switch" and "git restore" are introduced to
@ -68,7 +71,7 @@ UI, Workflows & Features
* The conditional inclusion mechanism learned to base the choice on * The conditional inclusion mechanism learned to base the choice on
the branch the HEAD currently is on. the branch the HEAD currently is on.
* "git rev-list --objects" learned with "--no-object-names" option to * "git rev-list --objects" learned the "--no-object-names" option to
squelch the path to the object that is used as a grouping hint for squelch the path to the object that is used as a grouping hint for
pack-objects. pack-objects.
@ -91,11 +94,6 @@ UI, Workflows & Features
commit-graph files now, which allows the commit-graph files to be commit-graph files now, which allows the commit-graph files to be
updated incrementally. updated incrementally.
* The "git log" command learns to issue a warning when log.mailmap
configuration is not set and --[no-]mailmap option is not used, to
prepare users for future versions of Git that uses the mailmap by
default.
* "git range-diff" output has been tweaked for easier identification * "git range-diff" output has been tweaked for easier identification
of which part of what file the patch shown is about. of which part of what file the patch shown is about.
@ -106,7 +104,7 @@ Performance, Internal Implementation, Development Support etc.
no longer be used. no longer be used.
* Developer support to emulate unsatisfied prerequisites in tests to * Developer support to emulate unsatisfied prerequisites in tests to
ensure that the remainer of the tests still succeeds when tests ensure that the remainder of the tests still succeeds when tests
with prerequisites are skipped. with prerequisites are skipped.
* "git update-server-info" learned not to rewrite the file with the * "git update-server-info" learned not to rewrite the file with the
@ -121,7 +119,7 @@ Performance, Internal Implementation, Development Support etc.
* Prepare use of reachability index in topological walker that works * Prepare use of reachability index in topological walker that works
on a range (A..B). on a range (A..B).
* A new tutorial targetting specifically aspiring git-core * A new tutorial targeting specifically aspiring git-core
developers has been added. developers has been added.
* Auto-detect how to tell HP-UX aCC where to use dynamically linked * Auto-detect how to tell HP-UX aCC where to use dynamically linked
@ -163,7 +161,6 @@ Performance, Internal Implementation, Development Support etc.
* We have been trying out a few language features outside c89; the * We have been trying out a few language features outside c89; the
coding guidelines document did not talk about them and instead had coding guidelines document did not talk about them and instead had
a blanket ban against them. a blanket ban against them.
(merge cc0c42975a jc/post-c89-rules-doc later to maint).
* A test helper has been introduced to optimize preparation of test * A test helper has been introduced to optimize preparation of test
repositories with many simple commits, and a handful of test repositories with many simple commits, and a handful of test
@ -177,16 +174,13 @@ Fixes since v2.22
ought to be relative to the directory "git init" gets invoked in, ought to be relative to the directory "git init" gets invoked in,
but it instead was made relative to the repository, which has been but it instead was made relative to the repository, which has been
corrected. corrected.
(merge e1df7fe43f nd/init-relative-template-fix later to maint).
* "git worktree add" used to fail when another worktree connected to * "git worktree add" used to fail when another worktree connected to
the same repository was corrupt, which has been corrected. the same repository was corrupt, which has been corrected.
(merge 105df73e71 nd/corrupt-worktrees later to maint).
* The ownership rule for the file descriptor to fast-import remote * The ownership rule for the file descriptor to fast-import remote
backend was mixed up, leading to unrelated file descriptor getting backend was mixed up, leading to an unrelated file descriptor getting
closed, which has been fixed. closed, which has been fixed.
(merge 3203566a71 mh/import-transport-fd-fix later to maint).
* A "merge -c" instruction during "git rebase --rebase-merges" should * A "merge -c" instruction during "git rebase --rebase-merges" should
give the user a chance to edit the log message, even when there is give the user a chance to edit the log message, even when there is
@ -195,82 +189,65 @@ Fixes since v2.22
corrected. corrected.
* Code cleanup and futureproof. * Code cleanup and futureproof.
(merge 31f5256c82 ds/object-info-for-prefetch-fix later to maint).
* More parameter validation. * More parameter validation.
(merge de99eb0c24 es/grep-require-name-when-needed later to maint).
* "git update-server-info" used to leave stale packfiles in its * "git update-server-info" used to leave stale packfiles in its
output, which has been corrected. output, which has been corrected.
(merge e941c48d49 ew/server-info-remove-crufts later to maint).
* The server side support for "git fetch" used to show incorrect * The server side support for "git fetch" used to show incorrect
value for the HEAD symbolic ref when the namespace feature is in value for the HEAD symbolic ref when the namespace feature is in
use, which has been corrected. use, which has been corrected.
(merge 533e088250 jk/HEAD-symref-in-xfer-namespaces later to maint).
* "git am -i --resolved" segfaulted after trying to see a commit as * "git am -i --resolved" segfaulted after trying to see a commit as
if it were a tree, which has been corrected. if it were a tree, which has been corrected.
(merge 7663e438c5 jk/am-i-resolved-fix later to maint).
* "git bundle verify" needs to see if prerequisite objects exist in * "git bundle verify" needs to see if prerequisite objects exist in
the receiving repository, but the command did not check if we are the receiving repository, but the command did not check if we are
in a repository upfront, which has been corrected. in a repository upfront, which has been corrected.
(merge 3bbbe467f2 js/bundle-verify-require-object-store later to maint).
* "git merge --squash" is designed to update the working tree and the * "git merge --squash" is designed to update the working tree and the
index without creating the commit, and this cannot be countermanded index without creating the commit, and this cannot be countermanded
by adding the "--commit" option; the command now refuses to work by adding the "--commit" option; the command now refuses to work
when both options are given. when both options are given.
(merge 1d14d0c994 vv/merge-squash-with-explicit-commit later to maint).
* The data collected by fsmonitor was not properly written back to * The data collected by fsmonitor was not properly written back to
the on-disk index file, breaking t7519 tests occasionally, which the on-disk index file, breaking t7519 tests occasionally, which
has been corrected. has been corrected.
(merge b5a8169752 js/fsmonitor-unflake later to maint).
* Update to Unicode 12.1 width table. * Update to Unicode 12.1 width table.
(merge 5817f9caa3 bb/unicode-12.1-reiwa later to maint).
* The command line to invoke a "git cat-file" command from inside * The command line to invoke a "git cat-file" command from inside
"git p4" was not properly quoted to protect a caret and running a "git p4" was not properly quoted to protect a caret and running a
broken command on Windows, which has been corrected. broken command on Windows, which has been corrected.
(merge c3f2358de3 mm/p4-unshelve-windows-fix later to maint).
* "git request-pull" learned to warn when the ref we ask them to pull * "git request-pull" learned to warn when the ref we ask them to pull
from in the local repository and in the published repository are from in the local repository and in the published repository are
different. different.
(merge 0454220d66 pb/request-pull-verify-remote-ref later to maint).
* When creating a partial clone, the object filtering criteria is * When creating a partial clone, the object filtering criteria is
recorded for the origin of the clone, but this incorrectly used a recorded for the origin of the clone, but this incorrectly used a
hardcoded name "origin" to name that remote; it has been corrected hardcoded name "origin" to name that remote; it has been corrected
to honor the "--origin <name>" option. to honor the "--origin <name>" option.
(merge 1c4a9f9114 xl/record-partial-clone-origin later to maint).
* "git fetch" into a lazy clone forgot to fetch base objects that are * "git fetch" into a lazy clone forgot to fetch base objects that are
necessary to complete delta in a thin packfile, which has been necessary to complete delta in a thin packfile, which has been
corrected. corrected.
(merge 810e19322d jt/partial-clone-missing-ref-delta-base later to maint).
* The filter_data used in the list-objects-filter (which manages a * The filter_data used in the list-objects-filter (which manages a
lazily sparse clone repository) did not use the dynamic array API lazily sparse clone repository) did not use the dynamic array API
correctly---'nr' is supposed to point at one past the last element correctly---'nr' is supposed to point at one past the last element
of the array in use. This has been corrected. of the array in use. This has been corrected.
(merge 7140600e2e md/list-objects-filter-memfix later to maint).
* The description about slashes in gitignore patterns (used to * The description about slashes in gitignore patterns (used to
indicate things like "anchored to this level only" and "only indicate things like "anchored to this level only" and "only
matches directories") has been revamped. matches directories") has been revamped.
(merge 1a58bad014 an/ignore-doc-update later to maint).
* The URL decoding code has been updated to avoid going past the end * The URL decoding code has been updated to avoid going past the end
of the string while parsing %-<hex>-<hex> sequence. of the string while parsing %-<hex>-<hex> sequence.
(merge d37dc239a4 md/url-parse-harden later to maint).
* The list of for-each like macros used by clang-format has been * The list of for-each like macros used by clang-format has been
updated. updated.
(merge fc7e03aace mo/clang-format-for-each-update later to maint).
* "git branch --list" learned to show branches that are checked out * "git branch --list" learned to show branches that are checked out
in other worktrees connected to the same repository prefixed with in other worktrees connected to the same repository prefixed with
@ -280,48 +257,38 @@ Fixes since v2.22
* Code restructuring during 2.20 period broke fetching tags via * Code restructuring during 2.20 period broke fetching tags via
"import" based transports. "import" based transports.
(merge f80d922355 fc/fetch-with-import-fix later to maint).
* The commit-graph file is now part of the "files that the runtime * The commit-graph file is now part of the "files that the runtime
may keep open file descriptors on, all of which would need to be may keep open file descriptors on, all of which would need to be
closed when done with the object store", and the file descriptor to closed when done with the object store", and the file descriptor to
an existing commit-graph file now is closed before "gc" finalizes a an existing commit-graph file now is closed before "gc" finalizes a
new instance to replace it. new instance to replace it.
(merge 2d511cfc0b ds/close-object-store later to maint).
* "git checkout -p" needs to selectively apply a patch in reverse, * "git checkout -p" needs to selectively apply a patch in reverse,
which did not work well. which did not work well.
(merge 2bd69b9024 pw/add-p-recount later to maint).
* Code clean-up to avoid signed integer wraparounds during binary search. * Code clean-up to avoid signed integer wraparounds during binary search.
(merge 568a05c5ec rs/avoid-overflow-in-midpoint-computation later to maint).
* "git interpret-trailers" always treated '#' as the comment * "git interpret-trailers" always treated '#' as the comment
character, regardless of core.commentChar setting, which has been character, regardless of core.commentChar setting, which has been
corrected. corrected.
(merge 29c83fc23f jk/trailers-use-config later to maint).
* "git stash show 23" used to work, but no more after getting * "git stash show 23" used to work, but no more after getting
rewritten in C; this regression has been corrected. rewritten in C; this regression has been corrected.
(merge 63b50c8ffe tg/stash-ref-by-index-fix later to maint).
* "git rebase --abort" used to leave refs/rewritten/ when concluding * "git rebase --abort" used to leave refs/rewritten/ when concluding
"git rebase -r", which has been corrected. "git rebase -r", which has been corrected.
(merge d559f502c5 pw/rebase-abort-clean-rewritten later to maint).
* An incorrect list of options was cached after command line * An incorrect list of options was cached after command line
completion failed (e.g. trying to complete a command that requires completion failed (e.g. trying to complete a command that requires
a repository outside one), which has been corrected. a repository outside one), which has been corrected.
(merge 69702523af nd/completion-no-cache-failure later to maint).
* The code to parse scaled numbers out of configuration files has * The code to parse scaled numbers out of configuration files has
been made more robust and also easier to follow. been made more robust and also easier to follow.
(merge 39c575c969 rs/config-unit-parsing later to maint).
* The codepath to compute delta islands used to spew progress output * The codepath to compute delta islands used to spew progress output
without giving the callers any way to squelch it, which has been without giving the callers any way to squelch it, which has been
fixed. fixed.
(merge bdbdf42f8a jk/delta-islands-progress-fix later to maint).
* Protocol capabilities that go over wire should never be translated, * Protocol capabilities that go over wire should never be translated,
but it was incorrectly marked for translation, which has been but it was incorrectly marked for translation, which has been
@ -330,23 +297,19 @@ Fixes since v2.22
* Use "Erase in Line" CSI sequence that is already used in the editor * Use "Erase in Line" CSI sequence that is already used in the editor
support to clear cruft in the progress output. support to clear cruft in the progress output.
(merge 5b12e3123b sg/rebase-progress later to maint).
* "git submodule foreach" did not protect command line options passed * "git submodule foreach" did not protect command line options passed
to the command to be run in each submodule correctly, when the to the command to be run in each submodule correctly, when the
"--recursive" option was in use. "--recursive" option was in use.
(merge 30db18b148 ms/submodule-foreach-fix later to maint).
* The configuration variable rebase.rescheduleFailedExec should be * The configuration variable rebase.rescheduleFailedExec should be
effective only while running an interactive rebase and should not effective only while running an interactive rebase and should not
affect anything when running an non-interactive one, which was not affect anything when running a non-interactive one, which was not
the case. This has been corrected. the case. This has been corrected.
(merge 906b63942a js/rebase-reschedule-applies-only-to-interactive later to maint).
* The "git clone" documentation refers to command line options in its * The "git clone" documentation refers to command line options in its
description in the short form; they have been replaced with long description in the short form; they have been replaced with long
forms to make them more recognisable. forms to make them more recognisable.
(merge bfc8c84ed5 qn/clone-doc-use-long-form later to maint).
* Generation of pack bitmaps are now disabled when .keep files exist, * Generation of pack bitmaps are now disabled when .keep files exist,
as these are mutually exclusive features. as these are mutually exclusive features.
@ -355,56 +318,31 @@ Fixes since v2.22
* "git rm" to resolve a conflicted path leaked an internal message * "git rm" to resolve a conflicted path leaked an internal message
"needs merge" before actually removing the path, which was "needs merge" before actually removing the path, which was
confusing. This has been corrected. confusing. This has been corrected.
(merge b2b1f615ce jc/denoise-rm-to-resolve later to maint).
* "git stash --keep-index" did not work correctly on paths that have * "git stash --keep-index" did not work correctly on paths that have
been removed, which has been fixed. been removed, which has been fixed.
(merge b932f6a5e8 tg/stash-keep-index-with-removed-paths later to maint). (merge b932f6a5e8 tg/stash-keep-index-with-removed-paths later to maint).
* Window 7 update ;-) * Window 7 update ;-)
(merge eb7c786314 js/mingw-spawn-with-spaces-in-path later to maint).
* A codepath that reads from GPG for signed object verification read * A codepath that reads from GPG for signed object verification read
past the end of allocated buffer, which has been fixed. past the end of allocated buffer, which has been fixed.
(merge 64c45dc72e sr/gpg-interface-stop-at-the-end later to maint).
* "git clean" silently skipped a path when it cannot lstat() it; now * "git clean" silently skipped a path when it cannot lstat() it; now
it gives a warning. it gives a warning.
(merge b09364c47a js/clean-report-too-long-a-path later to maint).
* "git push --atomic" that goes over the transport-helper (namely, * "git push --atomic" that goes over the transport-helper (namely,
the smart http transport) failed to prevent refs to be pushed when the smart http transport) failed to prevent refs to be pushed when
it can locally tell that one of the ref update will fail without it can locally tell that one of the ref update will fail without
having to consult the other end, which has been corrected. having to consult the other end, which has been corrected.
(merge 2581ea3d31 es/local-atomic-push-failure-with-http later to maint).
* The internal diff machinery can be made to read out of bounds while * The internal diff machinery can be made to read out of bounds while
looking for --funcion-context line in a corner case, which has been looking for --function-context line in a corner case, which has been
corrected. corrected.
(merge b777f3fd61 jk/xdiff-clamp-funcname-context-index later to maint). (merge b777f3fd61 jk/xdiff-clamp-funcname-context-index later to maint).
* Other code cleanup, docfix, build fix, etc. * Other code cleanup, docfix, build fix, etc.
(merge f547101b26 es/git-debugger-doc later to maint).
(merge 7877ac3d7b js/bisect-helper-check-get-oid-return-value later to maint).
(merge 0108f47eb3 sw/git-p4-unshelve-branched-files later to maint).
(merge 9df8f734fd cm/send-email-document-req-modules later to maint).
(merge afc3bf6eb1 ab/hash-object-doc later to maint).
(merge 1fde99cfc7 po/doc-branch later to maint).
(merge 459842e1c2 dl/config-alias-doc later to maint).
(merge 5d137fc2c7 cb/fsmonitor-intfix later to maint).
(merge 921d49be86 rs/copy-array later to maint).
(merge cc8d872e69 js/t3404-typofix later to maint).
(merge 729a9b558b cb/mkstemps-uint-type-fix later to maint).
(merge 9dae4fe79f js/gcc-8-and-9 later to maint).
(merge ed33bd8f30 js/t0001-case-insensitive later to maint).
(merge dfa880e336 jw/gitweb-sample-update later to maint).
(merge e532a90a9f sg/t5551-fetch-smart-error-is-translated later to maint).
(merge 8d45ad8c29 jt/t5551-test-chunked later to maint).
(merge 1a64e07d23 sg/git-C-empty-doc later to maint).
(merge 37a2e35395 sg/ci-brew-gcc-workaround later to maint).
(merge 24df0d49c4 js/trace2-signo-typofix later to maint).
(merge fbec05c210 cc/test-oidmap later to maint). (merge fbec05c210 cc/test-oidmap later to maint).
(merge 7926cee904 di/readme-markup-fix later to maint). (merge 7a06fb038c jk/no-system-includes-in-dot-c later to maint).
(merge 02638d1e11 vn/xmmap-gently later to maint). (merge 81ed2b405c cb/xdiff-no-system-includes-in-dot-c later to maint).
(merge f7bf24d4dd rm/gpg-program-doc-fix later to maint). (merge d61e6ce1dd sg/fsck-config-in-doc later to maint).
(merge 3aef54e8b8 js/unmap-before-ext-diff later to maint).

View File

@ -41,4 +41,4 @@ log.showSignature::
log.mailmap:: log.mailmap::
If true, makes linkgit:git-log[1], linkgit:git-show[1], and If true, makes linkgit:git-log[1], linkgit:git-show[1], and
linkgit:git-whatchanged[1] assume `--use-mailmap`, otherwise linkgit:git-whatchanged[1] assume `--use-mailmap`, otherwise
assume `--no-use-mailmap`. False by default. assume `--no-use-mailmap`. True by default.

View File

@ -17,7 +17,7 @@ linkgit:git-receive-pack[1]. On the fetch side, malformed objects will
instead be left unreferenced in the repository. instead be left unreferenced in the repository.
+ +
Due to the non-quarantine nature of the `fetch.fsckObjects` Due to the non-quarantine nature of the `fetch.fsckObjects`
implementation it can not be relied upon to leave the object store implementation it cannot be relied upon to leave the object store
clean like `receive.fsckObjects` can. clean like `receive.fsckObjects` can.
+ +
As objects are unpacked they're written to the object store, so there As objects are unpacked they're written to the object store, so there

View File

@ -232,7 +232,7 @@ write so it might not be enough to grant the users using
'git-cvsserver' write access to the database file without granting 'git-cvsserver' write access to the database file without granting
them write access to the directory, too. them write access to the directory, too.
The database can not be reliably regenerated in a The database cannot be reliably regenerated in a
consistent form after the branch it is tracking has changed. consistent form after the branch it is tracking has changed.
Example: For merged branches, 'git-cvsserver' only tracks Example: For merged branches, 'git-cvsserver' only tracks
one branch of development, and after a 'git merge' an one branch of development, and after a 'git merge' an

View File

@ -262,7 +262,7 @@ This updates (or creates, as necessary) branches `pu` and `tmp` in
the local repository by fetching from the branches (respectively) the local repository by fetching from the branches (respectively)
`pu` and `maint` from the remote repository. `pu` and `maint` from the remote repository.
+ +
The `pu` branch will be updated even if it is does not fast-forward, The `pu` branch will be updated even if it does not fast-forward,
because it is prefixed with a plus sign; `tmp` will not be. because it is prefixed with a plus sign; `tmp` will not be.
* Peek at a remote's branch, without configuring the remote in your local * Peek at a remote's branch, without configuring the remote in your local
@ -285,7 +285,7 @@ BUGS
---- ----
Using --recurse-submodules can only fetch new commits in already checked Using --recurse-submodules can only fetch new commits in already checked
out submodules right now. When e.g. upstream added a new submodule in the out submodules right now. When e.g. upstream added a new submodule in the
just fetched commits of the superproject the submodule itself can not be just fetched commits of the superproject the submodule itself cannot be
fetched, making it impossible to check out that submodule later without fetched, making it impossible to check out that submodule later without
having to do a fetch again. This is expected to be fixed in a future Git having to do a fetch again. This is expected to be fixed in a future Git
version. version.

View File

@ -104,6 +104,11 @@ care about this output and want to speed it up further.
progress status even if the standard error stream is not progress status even if the standard error stream is not
directed to a terminal. directed to a terminal.
CONFIGURATION
-------------
include::config/fsck.txt[]
DISCUSSION DISCUSSION
---------- ----------

View File

@ -249,7 +249,7 @@ BUGS
---- ----
Using --recurse-submodules can only fetch new commits in already checked Using --recurse-submodules can only fetch new commits in already checked
out submodules right now. When e.g. upstream added a new submodule in the out submodules right now. When e.g. upstream added a new submodule in the
just fetched commits of the superproject the submodule itself can not be just fetched commits of the superproject the submodule itself cannot be
fetched, making it impossible to check out that submodule later without fetched, making it impossible to check out that submodule later without
having to do a fetch again. This is expected to be fixed in a future Git having to do a fetch again. This is expected to be fixed in a future Git
version. version.

View File

@ -39,7 +39,7 @@ OPTIONS
commit, branch or tag associated with it. commit, branch or tag associated with it.
+ +
If not specified, the default restore source for the working tree is If not specified, the default restore source for the working tree is
the index, and the default restore source for the index index is the index, and the default restore source for the index is
`HEAD`. When both `--staged` and `--worktree` are specified, `HEAD`. When both `--staged` and `--worktree` are specified,
`--source` must also be specified. `--source` must also be specified.

View File

@ -255,7 +255,7 @@ This commit is referred to as a "merge commit", or sometimes just a
[[def_object]]object:: [[def_object]]object::
The unit of storage in Git. It is uniquely identified by the The unit of storage in Git. It is uniquely identified by the
<<def_SHA1,SHA-1>> of its contents. Consequently, an <<def_SHA1,SHA-1>> of its contents. Consequently, an
object can not be changed. object cannot be changed.
[[def_object_database]]object database:: [[def_object_database]]object database::
Stores a set of "objects", and an individual <<def_object,object>> is Stores a set of "objects", and an individual <<def_object,object>> is

View File

@ -54,7 +54,7 @@ this:
do not do this you will get an error for each ref that it does not point do not do this you will get an error for each ref that it does not point
to a valid object. to a valid object.
Note: As a side-effect of this you can not safely assume that all Note: As a side-effect of this you cannot safely assume that all
objects you lookup are available in superproject. All submodule objects objects you lookup are available in superproject. All submodule objects
will be available the same way as the superprojects objects. will be available the same way as the superprojects objects.

View File

@ -1,7 +1,7 @@
#!/bin/sh #!/bin/sh
GVF=GIT-VERSION-FILE GVF=GIT-VERSION-FILE
DEF_VER=v2.23.0-rc0 DEF_VER=v2.23.0-rc2
LF=' LF='
' '

View File

@ -2720,7 +2720,7 @@ bin-wrappers/%: wrap-for-bin.sh
@mkdir -p bin-wrappers @mkdir -p bin-wrappers
$(QUIET_GEN)sed -e '1s|#!.*/sh|#!$(SHELL_PATH_SQ)|' \ $(QUIET_GEN)sed -e '1s|#!.*/sh|#!$(SHELL_PATH_SQ)|' \
-e 's|@@BUILD_DIR@@|$(shell pwd)|' \ -e 's|@@BUILD_DIR@@|$(shell pwd)|' \
-e 's|@@PROG@@|$(patsubst test-%,t/helper/test-%,$(@F))|' < $< > $@ && \ -e 's|@@PROG@@|$(patsubst test-%,t/helper/test-%$(X),$(@F))$(patsubst git%,$(X),$(filter $(@F),$(BINDIR_PROGRAMS_NEED_X)))|' < $< > $@ && \
chmod +x $@ chmod +x $@
# GNU make supports exporting all variables by "export" without parameters. # GNU make supports exporting all variables by "export" without parameters.

View File

@ -1769,7 +1769,7 @@ int cmd_restore(int argc, const char **argv, const char *prefix)
struct option *options; struct option *options;
struct option restore_options[] = { struct option restore_options[] = {
OPT_STRING('s', "source", &opts.from_treeish, "<tree-ish>", OPT_STRING('s', "source", &opts.from_treeish, "<tree-ish>",
N_("where the checkout from")), N_("which tree-ish to checkout from")),
OPT_BOOL('S', "staged", &opts.checkout_index, OPT_BOOL('S', "staged", &opts.checkout_index,
N_("restore the index")), N_("restore the index")),
OPT_BOOL('W', "worktree", &opts.checkout_worktree, OPT_BOOL('W', "worktree", &opts.checkout_worktree,

View File

@ -850,6 +850,15 @@ static int iterate_ref_map(void *cb_data, struct object_id *oid)
return 0; return 0;
} }
static const char warn_show_forced_updates[] =
N_("Fetch normally indicates which branches had a forced update,\n"
"but that check has been disabled. To re-enable, use '--show-forced-updates'\n"
"flag or run 'git config fetch.showForcedUpdates true'.");
static const char warn_time_show_forced_updates[] =
N_("It took %.2f seconds to check forced updates. You can use\n"
"'--no-show-forced-updates' or run 'git config fetch.showForcedUpdates false'\n"
" to avoid this check.\n");
static int store_updated_refs(const char *raw_url, const char *remote_name, static int store_updated_refs(const char *raw_url, const char *remote_name,
int connectivity_checked, struct ref *ref_map) int connectivity_checked, struct ref *ref_map)
{ {
@ -1005,12 +1014,10 @@ static int store_updated_refs(const char *raw_url, const char *remote_name,
if (advice_fetch_show_forced_updates) { if (advice_fetch_show_forced_updates) {
if (!fetch_show_forced_updates) { if (!fetch_show_forced_updates) {
warning(_("Fetch normally indicates which branches had a forced update, but that check has been disabled.")); warning(_(warn_show_forced_updates));
warning(_("To re-enable, use '--show-forced-updates' flag or run 'git config fetch.showForcedUpdates true'."));
} else if (forced_updates_ms > FORCED_UPDATES_DELAY_WARNING_IN_MS) { } else if (forced_updates_ms > FORCED_UPDATES_DELAY_WARNING_IN_MS) {
warning(_("It took %.2f seconds to check forced updates. You can use '--no-show-forced-updates'\n"), warning(_(warn_time_show_forced_updates),
forced_updates_ms / 1000.0); forced_updates_ms / 1000.0);
warning(_("or run 'git config fetch.showForcedUpdates false' to avoid this check.\n"));
} }
} }

View File

@ -47,7 +47,7 @@ static int default_follow;
static int default_show_signature; static int default_show_signature;
static int decoration_style; static int decoration_style;
static int decoration_given; static int decoration_given;
static int use_mailmap_config = -1; static int use_mailmap_config = 1;
static const char *fmt_patch_subject_prefix = "PATCH"; static const char *fmt_patch_subject_prefix = "PATCH";
static const char *fmt_pretty; static const char *fmt_pretty;
@ -156,21 +156,11 @@ static void cmd_log_init_defaults(struct rev_info *rev)
parse_date_format(default_date_mode, &rev->date_mode); parse_date_format(default_date_mode, &rev->date_mode);
} }
static char warn_unspecified_mailmap_msg[] =
N_("log.mailmap is not set; its implicit value will change in an\n"
"upcoming release. To squelch this message and preserve current\n"
"behaviour, set the log.mailmap configuration value to false.\n"
"\n"
"To squelch this message and adopt the new behaviour now, set the\n"
"log.mailmap configuration value to true.\n"
"\n"
"See 'git help config' and search for 'log.mailmap' for further information.");
static void cmd_log_init_finish(int argc, const char **argv, const char *prefix, static void cmd_log_init_finish(int argc, const char **argv, const char *prefix,
struct rev_info *rev, struct setup_revision_opt *opt) struct rev_info *rev, struct setup_revision_opt *opt)
{ {
struct userformat_want w; struct userformat_want w;
int quiet = 0, source = 0, mailmap = 0; int quiet = 0, source = 0, mailmap;
static struct line_opt_callback_data line_cb = {NULL, NULL, STRING_LIST_INIT_DUP}; static struct line_opt_callback_data line_cb = {NULL, NULL, STRING_LIST_INIT_DUP};
static struct string_list decorate_refs_exclude = STRING_LIST_INIT_NODUP; static struct string_list decorate_refs_exclude = STRING_LIST_INIT_NODUP;
static struct string_list decorate_refs_include = STRING_LIST_INIT_NODUP; static struct string_list decorate_refs_include = STRING_LIST_INIT_NODUP;
@ -214,13 +204,6 @@ static void cmd_log_init_finish(int argc, const char **argv, const char *prefix,
memset(&w, 0, sizeof(w)); memset(&w, 0, sizeof(w));
userformat_find_requirements(NULL, &w); userformat_find_requirements(NULL, &w);
if (mailmap < 0) {
if (session_is_interactive() && !rev->pretty_given)
warning("%s\n", _(warn_unspecified_mailmap_msg));
mailmap = 0;
}
if (!rev->show_notes_given && (!rev->pretty_given || w.notes)) if (!rev->show_notes_given && (!rev->pretty_given || w.notes))
rev->show_notes = 1; rev->show_notes = 1;
if (rev->show_notes) if (rev->show_notes)

View File

@ -96,7 +96,11 @@ static off_t reuse_packfile_offset;
static int use_bitmap_index_default = 1; static int use_bitmap_index_default = 1;
static int use_bitmap_index = -1; static int use_bitmap_index = -1;
static int write_bitmap_index; static enum {
WRITE_BITMAP_FALSE = 0,
WRITE_BITMAP_QUIET,
WRITE_BITMAP_TRUE,
} write_bitmap_index;
static uint16_t write_bitmap_options = BITMAP_OPT_HASH_CACHE; static uint16_t write_bitmap_options = BITMAP_OPT_HASH_CACHE;
static int exclude_promisor_objects; static int exclude_promisor_objects;
@ -892,6 +896,7 @@ static void write_pack_file(void)
nr_written, oid.hash, offset); nr_written, oid.hash, offset);
close(fd); close(fd);
if (write_bitmap_index) { if (write_bitmap_index) {
if (write_bitmap_index != WRITE_BITMAP_QUIET)
warning(_(no_split_warning)); warning(_(no_split_warning));
write_bitmap_index = 0; write_bitmap_index = 0;
} }
@ -1176,6 +1181,7 @@ static int add_object_entry(const struct object_id *oid, enum object_type type,
if (!want_object_in_pack(oid, exclude, &found_pack, &found_offset)) { if (!want_object_in_pack(oid, exclude, &found_pack, &found_offset)) {
/* The pack is missing an object, so it will not have closure */ /* The pack is missing an object, so it will not have closure */
if (write_bitmap_index) { if (write_bitmap_index) {
if (write_bitmap_index != WRITE_BITMAP_QUIET)
warning(_(no_closure_warning)); warning(_(no_closure_warning));
write_bitmap_index = 0; write_bitmap_index = 0;
} }
@ -3313,8 +3319,13 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix)
N_("do not hide commits by grafts"), 0), N_("do not hide commits by grafts"), 0),
OPT_BOOL(0, "use-bitmap-index", &use_bitmap_index, OPT_BOOL(0, "use-bitmap-index", &use_bitmap_index,
N_("use a bitmap index if available to speed up counting objects")), N_("use a bitmap index if available to speed up counting objects")),
OPT_BOOL(0, "write-bitmap-index", &write_bitmap_index, OPT_SET_INT(0, "write-bitmap-index", &write_bitmap_index,
N_("write a bitmap index together with the pack index")), N_("write a bitmap index together with the pack index"),
WRITE_BITMAP_TRUE),
OPT_SET_INT_F(0, "write-bitmap-index-quiet",
&write_bitmap_index,
N_("write a bitmap index if possible"),
WRITE_BITMAP_QUIET, PARSE_OPT_HIDDEN),
OPT_PARSE_LIST_OBJECTS_FILTER(&filter_options), OPT_PARSE_LIST_OBJECTS_FILTER(&filter_options),
{ OPTION_CALLBACK, 0, "missing", NULL, N_("action"), { OPTION_CALLBACK, 0, "missing", NULL, N_("action"),
N_("handling for missing objects"), PARSE_OPT_NONEG, N_("handling for missing objects"), PARSE_OPT_NONEG,

View File

@ -89,17 +89,6 @@ static void remove_pack_on_signal(int signo)
raise(signo); raise(signo);
} }
static int has_pack_keep_file(void)
{
struct packed_git *p;
for (p = get_all_packs(the_repository); p; p = p->next) {
if (p->pack_keep)
return 1;
}
return 0;
}
/* /*
* Adds all packs hex strings to the fname list, which do not * Adds all packs hex strings to the fname list, which do not
* have a corresponding .keep file. These packs are not to * have a corresponding .keep file. These packs are not to
@ -345,13 +334,12 @@ int cmd_repack(int argc, const char **argv, const char *prefix)
die(_("--keep-unreachable and -A are incompatible")); die(_("--keep-unreachable and -A are incompatible"));
if (write_bitmaps < 0) { if (write_bitmaps < 0) {
write_bitmaps = (pack_everything & ALL_INTO_ONE) && if (!(pack_everything & ALL_INTO_ONE) ||
is_bare_repository() && !is_bare_repository())
keep_pack_list.nr == 0 && write_bitmaps = 0;
!has_pack_keep_file();
} }
if (pack_kept_objects < 0) if (pack_kept_objects < 0)
pack_kept_objects = write_bitmaps; pack_kept_objects = write_bitmaps > 0;
if (write_bitmaps && !(pack_everything & ALL_INTO_ONE)) if (write_bitmaps && !(pack_everything & ALL_INTO_ONE))
die(_(incremental_bitmap_conflict_error)); die(_(incremental_bitmap_conflict_error));
@ -375,8 +363,10 @@ int cmd_repack(int argc, const char **argv, const char *prefix)
argv_array_push(&cmd.args, "--indexed-objects"); argv_array_push(&cmd.args, "--indexed-objects");
if (repository_format_partial_clone) if (repository_format_partial_clone)
argv_array_push(&cmd.args, "--exclude-promisor-objects"); argv_array_push(&cmd.args, "--exclude-promisor-objects");
if (write_bitmaps) if (write_bitmaps > 0)
argv_array_push(&cmd.args, "--write-bitmap-index"); argv_array_push(&cmd.args, "--write-bitmap-index");
else if (write_bitmaps < 0)
argv_array_push(&cmd.args, "--write-bitmap-index-quiet");
if (use_delta_islands) if (use_delta_islands)
argv_array_push(&cmd.args, "--delta-islands"); argv_array_push(&cmd.args, "--delta-islands");

View File

@ -12,7 +12,6 @@
#include "repository.h" #include "repository.h"
#include "commit.h" #include "commit.h"
#include "run-command.h" #include "run-command.h"
#include <signal.h>
#include "parse-options.h" #include "parse-options.h"
#include "gpg-interface.h" #include "gpg-interface.h"

View File

@ -10,7 +10,6 @@
#include "builtin.h" #include "builtin.h"
#include "tag.h" #include "tag.h"
#include "run-command.h" #include "run-command.h"
#include <signal.h>
#include "parse-options.h" #include "parse-options.h"
#include "gpg-interface.h" #include "gpg-interface.h"
#include "ref-filter.h" #include "ref-filter.h"

View File

@ -434,6 +434,7 @@ static struct commit_graph *load_commit_graph_chain(struct repository *r, const
free(oids); free(oids);
fclose(fp); fclose(fp);
strbuf_release(&line);
return graph_chain; return graph_chain;
} }
@ -1186,7 +1187,7 @@ static int fill_oids_from_packs(struct write_commit_graph_context *ctx,
} }
stop_progress(&ctx->progress); stop_progress(&ctx->progress);
strbuf_reset(&progress_title); strbuf_release(&progress_title);
strbuf_release(&packname); strbuf_release(&packname);
return 0; return 0;
@ -1636,7 +1637,7 @@ static void sort_and_scan_merged_commits(struct write_commit_graph_context *ctx)
num_parents++; num_parents++;
if (num_parents > 2) if (num_parents > 2)
ctx->num_extra_edges += num_parents - 2; ctx->num_extra_edges += num_parents - 1;
} }
} }
@ -1713,10 +1714,8 @@ static void expire_commit_graphs(struct write_commit_graph_context *ctx)
strbuf_addstr(&path, "/info/commit-graphs"); strbuf_addstr(&path, "/info/commit-graphs");
dir = opendir(path.buf); dir = opendir(path.buf);
if (!dir) { if (!dir)
strbuf_release(&path); goto out;
return;
}
strbuf_addch(&path, '/'); strbuf_addch(&path, '/');
dirnamelen = path.len; dirnamelen = path.len;
@ -1745,6 +1744,9 @@ static void expire_commit_graphs(struct write_commit_graph_context *ctx)
if (!found) if (!found)
unlink(path.buf); unlink(path.buf);
} }
out:
strbuf_release(&path);
} }
int write_commit_graph(const char *obj_dir, int write_commit_graph(const char *obj_dir,

View File

@ -37,6 +37,29 @@ The Steps to Build Git with VS2015 or VS2017 from the command line.
================================================================ ================================================================
Alternatively, run `make vcxproj` and then load the generated `git.sln` in
Visual Studio. The initial build will install the vcpkg system and build the
dependencies automatically. This will take a while.
Instead of generating the `git.sln` file yourself (which requires a full Git
for Windows SDK), you may want to consider fetching the `vs/master` branch of
https://github.com/git-for-windows/git instead (which is updated automatically
via CI running `make vcxproj`). The `vs/master` branch does not require a Git
for Windows to build, but you can run the test scripts in a regular Git Bash.
Note that `make vcxproj` will automatically add and commit the generated `.sln`
and `.vcxproj` files to the repo. This is necessary to allow building a
fully-testable Git in Visual Studio, where a regular Git Bash can be used to
run the test scripts (as opposed to a full Git for Windows SDK): a number of
build targets, such as Git commands implemented as Unix shell scripts (where
`@@SHELL_PATH@@` and other placeholders are interpolated) require a full-blown
Git for Windows SDK (which is about 10x the size of a regular Git for Windows
installation).
If your plan is to open a Pull Request with Git for Windows, it is a good idea
to drop this commit before submitting.
================================================================
The Steps of Build Git with VS2008 The Steps of Build Git with VS2008
1. You need the build environment, which contains the Git dependencies 1. You need the build environment, which contains the Git dependencies

View File

@ -275,7 +275,8 @@ static int include_by_branch(const char *cond, size_t cond_len)
int flags; int flags;
int ret; int ret;
struct strbuf pattern = STRBUF_INIT; struct strbuf pattern = STRBUF_INIT;
const char *refname = resolve_ref_unsafe("HEAD", 0, NULL, &flags); const char *refname = !the_repository || !the_repository->gitdir ?
NULL : resolve_ref_unsafe("HEAD", 0, NULL, &flags);
const char *shortname; const char *shortname;
if (!refname || !(flags & REF_ISSYMREF) || if (!refname || !(flags & REF_ISSYMREF) ||

View File

@ -25,10 +25,12 @@ include compat/vcbuild/MSVC-DEFS-GEN
# See if vcpkg and the vcpkg-build versions of the third-party # See if vcpkg and the vcpkg-build versions of the third-party
# libraries that we use are installed. We include the result # libraries that we use are installed. We include the result
# to get $(vcpkg_*) variables defined for the Makefile. # to get $(vcpkg_*) variables defined for the Makefile.
ifeq (,$(SKIP_VCPKG))
compat/vcbuild/VCPKG-DEFS: compat/vcbuild/vcpkg_install.bat compat/vcbuild/VCPKG-DEFS: compat/vcbuild/vcpkg_install.bat
@"$<" @"$<"
include compat/vcbuild/VCPKG-DEFS include compat/vcbuild/VCPKG-DEFS
endif endif
endif
# We choose to avoid "if .. else if .. else .. endif endif" # We choose to avoid "if .. else if .. else .. endif endif"
# because maintaining the nesting to match is a pain. If # because maintaining the nesting to match is a pain. If
@ -689,3 +691,77 @@ ifeq ($(uname_S),QNX)
NO_STRCASESTR = YesPlease NO_STRCASESTR = YesPlease
NO_STRLCPY = YesPlease NO_STRLCPY = YesPlease
endif endif
vcxproj:
# Require clean work tree
git update-index -q --refresh && \
git diff-files --quiet && \
git diff-index --cached --quiet HEAD --
# Make .vcxproj files and add them
unset QUIET_GEN QUIET_BUILT_IN; \
perl contrib/buildsystems/generate -g Vcxproj
git add -f git.sln {*,*/lib,t/helper/*}/*.vcxproj
# Generate the LinkOrCopyBuiltins.targets file
(echo '<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">' && \
echo ' <Target Name="CopyBuiltins_AfterBuild" AfterTargets="AfterBuild">' && \
for name in $(BUILT_INS);\
do \
echo ' <Copy SourceFiles="$$(OutDir)\git.exe" DestinationFiles="$$(OutDir)\'"$$name"'" SkipUnchangedFiles="true" UseHardlinksIfPossible="true" />'; \
done && \
for name in $(REMOTE_CURL_ALIASES); \
do \
echo ' <Copy SourceFiles="$$(OutDir)\'"$(REMOTE_CURL_PRIMARY)"'" DestinationFiles="$$(OutDir)\'"$$name"'" SkipUnchangedFiles="true" UseHardlinksIfPossible="true" />'; \
done && \
echo ' </Target>' && \
echo '</Project>') >git/LinkOrCopyBuiltins.targets
git add -f git/LinkOrCopyBuiltins.targets
# Add command-list.h
$(MAKE) MSVC=1 SKIP_VCPKG=1 prefix=/mingw64 command-list.h
git add -f command-list.h
# Add scripts
rm -f perl/perl.mak
$(MAKE) MSVC=1 SKIP_VCPKG=1 prefix=/mingw64 \
$(SCRIPT_LIB) $(SCRIPT_SH_GEN) $(SCRIPT_PERL_GEN)
# Strip out the sane tool path, needed only for building
sed -i '/^git_broken_path_fix ".*/d' git-sh-setup
git add -f $(SCRIPT_LIB) $(SCRIPT_SH_GEN) $(SCRIPT_PERL_GEN)
# Add Perl module
$(MAKE) $(LIB_PERL_GEN)
git add -f perl/build
# Add bin-wrappers, for testing
rm -rf bin-wrappers/
$(MAKE) MSVC=1 SKIP_VCPKG=1 prefix=/mingw64 $(test_bindir_programs)
# Ensure that the GIT_EXEC_PATH is a Unix-y one, and that the absolute
# path of the repository is not hard-coded (GIT_EXEC_PATH will be set
# by test-lib.sh according to the current setup)
sed -i -e 's/^\(GIT_EXEC_PATH\)=.*/test -n "$${\1##*:*}" ||\
\1="$$(cygpath -u "$$\1")"/' \
-e "s|'$$(pwd)|\"\$$GIT_EXEC_PATH\"'|g" bin-wrappers/*
# Ensure that test-* helpers find the .dll files copied to top-level
sed -i 's|^PATH=.*|&:"$$GIT_EXEC_PATH"|' bin-wrappers/test-*
# We do not want to force hard-linking builtins
sed -i 's|\(git\)-\([-a-z]*\)\.exe"|\1.exe" \2|g' \
bin-wrappers/git-{receive-pack,upload-archive}
git add -f $(test_bindir_programs)
# remote-ext is a builtin, but invoked as if it were external
sed 's|receive-pack|remote-ext|g' \
<bin-wrappers/git-receive-pack >bin-wrappers/git-remote-ext
git add -f bin-wrappers/git-remote-ext
# Add templates
$(MAKE) -C templates
git add -f templates/boilerplates.made templates/blt/
# Add build options
$(MAKE) MSVC=1 SKIP_VCPKG=1 prefix=/mingw64 GIT-BUILD-OPTIONS
git add -f GIT-BUILD-OPTIONS
# Commit the whole shebang
git commit -m "Generate Visual Studio solution" \
-m "Auto-generated by \`$(MAKE)$(MAKEFLAGS) $@\`"

View File

@ -17,7 +17,7 @@ BEGIN {
$me = dirname($me); $me = dirname($me);
if (opendir(D,"$me/Generators")) { if (opendir(D,"$me/Generators")) {
foreach my $gen (readdir(D)) { foreach my $gen (readdir(D)) {
next if ($gen =~ /^\.\.?$/); next unless ($gen =~ /\.pm$/);
require "${me}/Generators/$gen"; require "${me}/Generators/$gen";
$gen =~ s,\.pm,,; $gen =~ s,\.pm,,;
push(@AVAILABLE, $gen); push(@AVAILABLE, $gen);

View File

@ -3,6 +3,7 @@ require Exporter;
use strict; use strict;
use vars qw($VERSION); use vars qw($VERSION);
use Digest::SHA qw(sha256_hex);
our $VERSION = '1.00'; our $VERSION = '1.00';
our(@ISA, @EXPORT, @EXPORT_OK, @AVAILABLE); our(@ISA, @EXPORT, @EXPORT_OK, @AVAILABLE);
@ -12,59 +13,12 @@ BEGIN {
push @EXPORT_OK, qw(generate); push @EXPORT_OK, qw(generate);
} }
my $guid_index = 0; sub generate_guid ($) {
my @GUIDS = ( my $hex = sha256_hex($_[0]);
"{E07B9989-2BF7-4F21-8918-BE22BA467AC3}", $hex =~ s/^(.{8})(.{4})(.{4})(.{4})(.{12}).*/{$1-$2-$3-$4-$5}/;
"{278FFB51-0296-4A44-A81A-22B87B7C3592}", $hex =~ tr/a-z/A-Z/;
"{7346A2C4-F0FD-444F-9EBE-1AF23B2B5650}", return $hex;
"{67F421AC-EB34-4D49-820B-3196807B423F}", }
"{385DCFE1-CC8C-4211-A451-80FCFC31CA51}",
"{97CC46C5-D2CC-4D26-B634-E75792B79916}",
"{C7CE21FE-6EF8-4012-A5C7-A22BCEDFBA11}",
"{51575134-3FDF-42D1-BABD-3FB12669C6C9}",
"{0AE195E4-9823-4B87-8E6F-20C5614AF2FF}",
"{4B918255-67CA-43BB-A46C-26704B666E6B}",
"{18CCFEEF-C8EE-4CC1-A265-26F95C9F4649}",
"{5D5D90FA-01B7-4973-AFE5-CA88C53AC197}",
"{1F054320-036D-49E1-B384-FB5DF0BC8AC0}",
"{7CED65EE-F2D9-4171-825B-C7D561FE5786}",
"{8D341679-0F07-4664-9A56-3BA0DE88B9BC}",
"{C189FEDC-2957-4BD7-9FA4-7622241EA145}",
"{66844203-1B9F-4C53-9274-164FFF95B847}",
"{E4FEA145-DECC-440D-AEEA-598CF381FD43}",
"{73300A8E-C8AC-41B0-B555-4F596B681BA7}",
"{873FDEB1-D01D-40BF-A1BF-8BBC58EC0F51}",
"{7922C8BE-76C5-4AC6-8BF7-885C0F93B782}",
"{E245D370-308B-4A49-BFC1-1E527827975F}",
"{F6FA957B-66FC-4ED7-B260-E59BBE4FE813}",
"{E6055070-0198-431A-BC49-8DB6CEE770AE}",
"{54159234-C3EB-43DA-906B-CE5DA5C74654}",
"{594CFC35-0B60-46F6-B8EF-9983ACC1187D}",
"{D93FCAB7-1F01-48D2-B832-F761B83231A5}",
"{DBA5E6AC-E7BE-42D3-8703-4E787141526E}",
"{6171953F-DD26-44C7-A3BE-CC45F86FC11F}",
"{9E19DDBE-F5E4-4A26-A2FE-0616E04879B8}",
"{AE81A615-99E3-4885-9CE0-D9CAA193E867}",
"{FBF4067E-1855-4F6C-8BCD-4D62E801A04D}",
"{17007948-6593-4AEB-8106-F7884B4F2C19}",
"{199D4C8D-8639-4DA6-82EF-08668C35DEE0}",
"{E085E50E-C140-4CF3-BE4B-094B14F0DDD6}",
"{00785268-A9CC-4E40-AC29-BAC0019159CE}",
"{4C06F56A-DCDB-46A6-B67C-02339935CF12}",
"{3A62D3FD-519E-4EC9-8171-D2C1BFEA022F}",
"{3A62D3FD-519E-4EC9-8171-D2C1BFEA022F}",
"{9392EB58-D7BA-410B-B1F0-B2FAA6BC89A7}",
"{2ACAB2D5-E0CE-4027-BCA0-D78B2D7A6C66}",
"{86E216C3-43CE-481A-BCB2-BE5E62850635}",
"{FB631291-7923-4B91-9A57-7B18FDBB7A42}",
"{0A176EC9-E934-45B8-B87F-16C7F4C80039}",
"{DF55CA80-46E8-4C53-B65B-4990A23DD444}",
"{3A0F9895-55D2-4710-BE5E-AD7498B5BF44}",
"{294BDC5A-F448-48B6-8110-DD0A81820F8C}",
"{4B9F66E9-FAC9-47AB-B1EF-C16756FBFD06}",
"{72EA49C6-2806-48BD-B81B-D4905102E19C}",
"{5728EB7E-8929-486C-8CD5-3238D060E768}"
);
sub generate { sub generate {
my ($git_dir, $out_dir, $rel_dir, %build_structure) = @_; my ($git_dir, $out_dir, $rel_dir, %build_structure) = @_;
@ -92,9 +46,8 @@ sub createLibProject {
$target =~ s/\//_/g; $target =~ s/\//_/g;
$target =~ s/\.a//; $target =~ s/\.a//;
my $uuid = $GUIDS[$guid_index]; my $uuid = generate_guid($libname);
$$build_structure{"LIBS_${target}_GUID"} = $uuid; $$build_structure{"LIBS_${target}_GUID"} = $uuid;
$guid_index += 1;
my @srcs = sort(map("$rel_dir\\$_", @{$$build_structure{"LIBS_${libname}_SOURCES"}})); my @srcs = sort(map("$rel_dir\\$_", @{$$build_structure{"LIBS_${libname}_SOURCES"}}));
my @sources; my @sources;
@ -106,6 +59,8 @@ sub createLibProject {
my $includes= join(";", sort(map("&quot;$rel_dir\\$_&quot;", @{$$build_structure{"LIBS_${libname}_INCLUDES"}}))); my $includes= join(";", sort(map("&quot;$rel_dir\\$_&quot;", @{$$build_structure{"LIBS_${libname}_INCLUDES"}})));
my $cflags = join(" ", sort(@{$$build_structure{"LIBS_${libname}_CFLAGS"}})); my $cflags = join(" ", sort(@{$$build_structure{"LIBS_${libname}_CFLAGS"}}));
$cflags =~ s/\"/&quot;/g; $cflags =~ s/\"/&quot;/g;
$cflags =~ s/</&lt;/g;
$cflags =~ s/>/&gt;/g;
my $cflags_debug = $cflags; my $cflags_debug = $cflags;
$cflags_debug =~ s/-MT/-MTd/; $cflags_debug =~ s/-MT/-MTd/;
@ -127,6 +82,8 @@ sub createLibProject {
$defines =~ s/-D//g; $defines =~ s/-D//g;
$defines =~ s/\"/\\&quot;/g; $defines =~ s/\"/\\&quot;/g;
$defines =~ s/</&lt;/g;
$defines =~ s/>/&gt;/g;
$defines =~ s/\'//g; $defines =~ s/\'//g;
$includes =~ s/-I//g; $includes =~ s/-I//g;
mkdir "$target" || die "Could not create the directory $target for lib project!\n"; mkdir "$target" || die "Could not create the directory $target for lib project!\n";
@ -162,9 +119,6 @@ sub createLibProject {
<Tool <Tool
Name="VCXMLDataGeneratorTool" Name="VCXMLDataGeneratorTool"
/> />
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool <Tool
Name="VCMIDLTool" Name="VCMIDLTool"
/> />
@ -228,9 +182,6 @@ sub createLibProject {
<Tool <Tool
Name="VCXMLDataGeneratorTool" Name="VCXMLDataGeneratorTool"
/> />
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool <Tool
Name="VCMIDLTool" Name="VCMIDLTool"
/> />
@ -311,9 +262,8 @@ sub createAppProject {
$target =~ s/\//_/g; $target =~ s/\//_/g;
$target =~ s/\.exe//; $target =~ s/\.exe//;
my $uuid = $GUIDS[$guid_index]; my $uuid = generate_guid($appname);
$$build_structure{"APPS_${target}_GUID"} = $uuid; $$build_structure{"APPS_${target}_GUID"} = $uuid;
$guid_index += 1;
my @srcs = sort(map("$rel_dir\\$_", @{$$build_structure{"APPS_${appname}_SOURCES"}})); my @srcs = sort(map("$rel_dir\\$_", @{$$build_structure{"APPS_${appname}_SOURCES"}}));
my @sources; my @sources;
@ -325,6 +275,8 @@ sub createAppProject {
my $includes= join(";", sort(map("&quot;$rel_dir\\$_&quot;", @{$$build_structure{"APPS_${appname}_INCLUDES"}}))); my $includes= join(";", sort(map("&quot;$rel_dir\\$_&quot;", @{$$build_structure{"APPS_${appname}_INCLUDES"}})));
my $cflags = join(" ", sort(@{$$build_structure{"APPS_${appname}_CFLAGS"}})); my $cflags = join(" ", sort(@{$$build_structure{"APPS_${appname}_CFLAGS"}}));
$cflags =~ s/\"/&quot;/g; $cflags =~ s/\"/&quot;/g;
$cflags =~ s/</&lt;/g;
$cflags =~ s/>/&gt;/g;
my $cflags_debug = $cflags; my $cflags_debug = $cflags;
$cflags_debug =~ s/-MT/-MTd/; $cflags_debug =~ s/-MT/-MTd/;
@ -351,6 +303,8 @@ sub createAppProject {
$defines =~ s/-D//g; $defines =~ s/-D//g;
$defines =~ s/\"/\\&quot;/g; $defines =~ s/\"/\\&quot;/g;
$defines =~ s/</&lt;/g;
$defines =~ s/>/&gt;/g;
$defines =~ s/\'//g; $defines =~ s/\'//g;
$defines =~ s/\\\\/\\/g; $defines =~ s/\\\\/\\/g;
$includes =~ s/-I//g; $includes =~ s/-I//g;
@ -387,9 +341,6 @@ sub createAppProject {
<Tool <Tool
Name="VCXMLDataGeneratorTool" Name="VCXMLDataGeneratorTool"
/> />
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool <Tool
Name="VCMIDLTool" Name="VCMIDLTool"
/> />
@ -458,9 +409,6 @@ sub createAppProject {
<Tool <Tool
Name="VCXMLDataGeneratorTool" Name="VCXMLDataGeneratorTool"
/> />
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool <Tool
Name="VCMIDLTool" Name="VCMIDLTool"
/> />
@ -561,20 +509,18 @@ sub createGlueProject {
foreach (@apps) { foreach (@apps) {
$_ =~ s/\//_/g; $_ =~ s/\//_/g;
$_ =~ s/\.exe//; $_ =~ s/\.exe//;
if ($_ eq "git" ) {
unshift(@tmp, $_);
} else {
push(@tmp, $_); push(@tmp, $_);
} }
}
@apps = @tmp; @apps = @tmp;
open F, ">git.sln" || die "Could not open git.sln for writing!\n"; open F, ">git.sln" || die "Could not open git.sln for writing!\n";
binmode F, ":crlf"; binmode F, ":crlf";
print F "$SLN_HEAD"; print F "$SLN_HEAD";
foreach (@libs) {
my $libname = $_;
my $uuid = $build_structure{"LIBS_${libname}_GUID"};
print F "$SLN_PRE";
print F "\"${libname}\", \"${libname}\\${libname}.vcproj\", \"${uuid}\"";
print F "$SLN_POST";
}
my $uuid_libgit = $build_structure{"LIBS_libgit_GUID"}; my $uuid_libgit = $build_structure{"LIBS_libgit_GUID"};
my $uuid_xdiff_lib = $build_structure{"LIBS_xdiff_lib_GUID"}; my $uuid_xdiff_lib = $build_structure{"LIBS_xdiff_lib_GUID"};
foreach (@apps) { foreach (@apps) {
@ -588,6 +534,13 @@ sub createGlueProject {
print F " EndProjectSection"; print F " EndProjectSection";
print F "$SLN_POST"; print F "$SLN_POST";
} }
foreach (@libs) {
my $libname = $_;
my $uuid = $build_structure{"LIBS_${libname}_GUID"};
print F "$SLN_PRE";
print F "\"${libname}\", \"${libname}\\${libname}.vcproj\", \"${uuid}\"";
print F "$SLN_POST";
}
print F << "EOM"; print F << "EOM";
Global Global
@ -599,17 +552,17 @@ EOM
print F << "EOM"; print F << "EOM";
GlobalSection(ProjectConfigurationPlatforms) = postSolution GlobalSection(ProjectConfigurationPlatforms) = postSolution
EOM EOM
foreach (@libs) { foreach (@apps) {
my $libname = $_; my $appname = $_;
my $uuid = $build_structure{"LIBS_${libname}_GUID"}; my $uuid = $build_structure{"APPS_${appname}_GUID"};
print F "\t\t${uuid}.Debug|Win32.ActiveCfg = Debug|Win32\n"; print F "\t\t${uuid}.Debug|Win32.ActiveCfg = Debug|Win32\n";
print F "\t\t${uuid}.Debug|Win32.Build.0 = Debug|Win32\n"; print F "\t\t${uuid}.Debug|Win32.Build.0 = Debug|Win32\n";
print F "\t\t${uuid}.Release|Win32.ActiveCfg = Release|Win32\n"; print F "\t\t${uuid}.Release|Win32.ActiveCfg = Release|Win32\n";
print F "\t\t${uuid}.Release|Win32.Build.0 = Release|Win32\n"; print F "\t\t${uuid}.Release|Win32.Build.0 = Release|Win32\n";
} }
foreach (@apps) { foreach (@libs) {
my $appname = $_; my $libname = $_;
my $uuid = $build_structure{"APPS_${appname}_GUID"}; my $uuid = $build_structure{"LIBS_${libname}_GUID"};
print F "\t\t${uuid}.Debug|Win32.ActiveCfg = Debug|Win32\n"; print F "\t\t${uuid}.Debug|Win32.ActiveCfg = Debug|Win32\n";
print F "\t\t${uuid}.Debug|Win32.Build.0 = Debug|Win32\n"; print F "\t\t${uuid}.Debug|Win32.Build.0 = Debug|Win32\n";
print F "\t\t${uuid}.Release|Win32.ActiveCfg = Release|Win32\n"; print F "\t\t${uuid}.Release|Win32.ActiveCfg = Release|Win32\n";

View File

@ -0,0 +1,388 @@
package Generators::Vcxproj;
require Exporter;
use strict;
use vars qw($VERSION);
use Digest::SHA qw(sha256_hex);
our $VERSION = '1.00';
our(@ISA, @EXPORT, @EXPORT_OK, @AVAILABLE);
@ISA = qw(Exporter);
BEGIN {
push @EXPORT_OK, qw(generate);
}
sub generate_guid ($) {
my $hex = sha256_hex($_[0]);
$hex =~ s/^(.{8})(.{4})(.{4})(.{4})(.{12}).*/{$1-$2-$3-$4-$5}/;
$hex =~ tr/a-z/A-Z/;
return $hex;
}
sub generate {
my ($git_dir, $out_dir, $rel_dir, %build_structure) = @_;
my @libs = @{$build_structure{"LIBS"}};
foreach (@libs) {
createProject($_, $git_dir, $out_dir, $rel_dir, \%build_structure, 1);
}
my @apps = @{$build_structure{"APPS"}};
foreach (@apps) {
createProject($_, $git_dir, $out_dir, $rel_dir, \%build_structure, 0);
}
createGlueProject($git_dir, $out_dir, $rel_dir, %build_structure);
return 0;
}
sub createProject {
my ($name, $git_dir, $out_dir, $rel_dir, $build_structure, $static_library) = @_;
my $label = $static_library ? "lib" : "app";
my $prefix = $static_library ? "LIBS_" : "APPS_";
my $config_type = $static_library ? "StaticLibrary" : "Application";
print "Generate $name vcxproj $label project\n";
my $cdup = $name;
$cdup =~ s/[^\/]+/../g;
$cdup =~ s/\//\\/g;
$rel_dir = $rel_dir eq "." ? $cdup : "$cdup\\$rel_dir";
$rel_dir =~ s/\//\\/g;
my $target = $name;
if ($static_library) {
$target =~ s/\.a//;
} else {
$target =~ s/\.exe//;
}
my $uuid = generate_guid($name);
$$build_structure{"$prefix${target}_GUID"} = $uuid;
my $vcxproj = $target;
$vcxproj =~ s/(.*\/)?(.*)/$&\/$2.vcxproj/;
$vcxproj =~ s/([^\/]*)(\/lib)\/(lib.vcxproj)/$1$2\/$1_$3/;
$$build_structure{"$prefix${target}_VCXPROJ"} = $vcxproj;
my @srcs = sort(map("$rel_dir\\$_", @{$$build_structure{"$prefix${name}_SOURCES"}}));
my @sources;
foreach (@srcs) {
$_ =~ s/\//\\/g;
push(@sources, $_);
}
my $defines = join(";", sort(@{$$build_structure{"$prefix${name}_DEFINES"}}));
my $includes= join(";", sort(map { s/^-I//; s/\//\\/g; File::Spec->file_name_is_absolute($_) ? $_ : "$rel_dir\\$_" } @{$$build_structure{"$prefix${name}_INCLUDES"}}));
my $cflags = join(" ", sort(map { s/^-[GLMOWZ].*//; s/.* .*/"$&"/; $_; } @{$$build_structure{"$prefix${name}_CFLAGS"}}));
$cflags =~ s/</&lt;/g;
$cflags =~ s/>/&gt;/g;
my $libs_release = "\n ";
my $libs_debug = "\n ";
if (!$static_library) {
$libs_release = join(";", sort(grep /^(?!libgit\.lib|xdiff\/lib\.lib|vcs-svn\/lib\.lib)/, @{$$build_structure{"$prefix${name}_LIBS"}}));
$libs_debug = $libs_release;
$libs_debug =~ s/zlib\.lib/zlibd\.lib/;
}
$defines =~ s/-D//g;
$defines =~ s/</&lt;/g;
$defines =~ s/>/&gt;/g;
$defines =~ s/\'//g;
die "Could not create the directory $target for $label project!\n" unless (-d "$target" || mkdir "$target");
open F, ">$vcxproj" or die "Could not open $vcxproj for writing!\n";
binmode F, ":crlf :utf8";
print F chr(0xFEFF);
print F << "EOM";
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>$uuid</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<VCPKGArch Condition="'\$(Platform)'=='Win32'">x86-windows</VCPKGArch>
<VCPKGArch Condition="'\$(Platform)'!='Win32'">x64-windows</VCPKGArch>
<VCPKGArchDirectory>$cdup\\compat\\vcbuild\\vcpkg\\installed\\\$(VCPKGArch)</VCPKGArchDirectory>
<VCPKGBinDirectory Condition="'\(Configuration)'=='Debug'">\$(VCPKGArchDirectory)\\debug\\bin</VCPKGBinDirectory>
<VCPKGLibDirectory Condition="'\(Configuration)'=='Debug'">\$(VCPKGArchDirectory)\\debug\\lib</VCPKGLibDirectory>
<VCPKGBinDirectory Condition="'\(Configuration)'!='Debug'">\$(VCPKGArchDirectory)\\bin</VCPKGBinDirectory>
<VCPKGLibDirectory Condition="'\(Configuration)'!='Debug'">\$(VCPKGArchDirectory)\\lib</VCPKGLibDirectory>
<VCPKGIncludeDirectory>\$(VCPKGArchDirectory)\\include</VCPKGIncludeDirectory>
<VCPKGLibs Condition="'\(Configuration)'=='Debug'">$libs_debug</VCPKGLibs>
<VCPKGLibs Condition="'\(Configuration)'!='Debug'">$libs_release</VCPKGLibs>
</PropertyGroup>
<Import Project="\$(VCTargetsPath)\\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'\$(Configuration)'=='Debug'" Label="Configuration">
<UseDebugLibraries>true</UseDebugLibraries>
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'\$(Configuration)'=='Release'" Label="Configuration">
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
</PropertyGroup>
<PropertyGroup>
<ConfigurationType>$config_type</ConfigurationType>
<PlatformToolset>v140</PlatformToolset>
<!-- <CharacterSet>UTF-8</CharacterSet> -->
<OutDir>..\\</OutDir>
<!-- <IntDir>\$(ProjectDir)\$(Configuration)\\</IntDir> -->
</PropertyGroup>
<Import Project="\$(VCTargetsPath)\\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="Shared">
</ImportGroup>
<ImportGroup Label="PropertySheets">
<Import Project="\$(UserRootDir)\\Microsoft.Cpp.\$(Platform).user.props" Condition="exists('\$(UserRootDir)\\Microsoft.Cpp.\$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<GenerateManifest>false</GenerateManifest>
<EnableManagedIncrementalBuild>true</EnableManagedIncrementalBuild>
</PropertyGroup>
<ItemDefinitionGroup>
<ClCompile>
<AdditionalOptions>$cflags %(AdditionalOptions)</AdditionalOptions>
<AdditionalIncludeDirectories>$cdup;$cdup\\compat;$cdup\\compat\\regex;$cdup\\compat\\win32;$cdup\\compat\\poll;$cdup\\compat\\vcbuild\\include;\$(VCPKGIncludeDirectory);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<EnableParallelCodeGeneration />
<InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
<PrecompiledHeader />
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
</ClCompile>
<Lib>
<SuppressStartupBanner>true</SuppressStartupBanner>
</Lib>
<Link>
<AdditionalLibraryDirectories>\$(VCPKGLibDirectory);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalDependencies>\$(VCPKGLibs);\$(AdditionalDependencies)</AdditionalDependencies>
<AdditionalOptions>invalidcontinue.obj %(AdditionalOptions)</AdditionalOptions>
<EntryPointSymbol>wmainCRTStartup</EntryPointSymbol>
<ManifestFile>$cdup\\compat\\win32\\git.manifest</ManifestFile>
<SubSystem>Console</SubSystem>
</Link>
EOM
if ($target eq 'libgit') {
print F << "EOM";
<PreBuildEvent Condition="!Exists('$cdup\\compat\\vcbuild\\vcpkg\\installed\\\$(VCPKGArch)\\include\\openssl\\ssl.h')">
<Message>Initialize VCPKG</Message>
<Command>del "$cdup\\compat\\vcbuild\\vcpkg"</Command>
<Command>call "$cdup\\compat\\vcbuild\\vcpkg_install.bat"</Command>
</PreBuildEvent>
EOM
}
print F << "EOM";
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'\$(Platform)'=='Win32'">
<Link>
<TargetMachine>MachineX86</TargetMachine>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'\$(Configuration)'=='Debug'">
<ClCompile>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;$defines;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'\$(Configuration)'=='Release'">
<ClCompile>
<Optimization>MaxSpeed</Optimization>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;$defines;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<FunctionLevelLinking>true</FunctionLevelLinking>
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
EOM
foreach(@sources) {
print F << "EOM";
<ClCompile Include="$_" />
EOM
}
print F << "EOM";
</ItemGroup>
EOM
if (!$static_library || $target =~ 'vcs-svn' || $target =~ 'xdiff') {
my $uuid_libgit = $$build_structure{"LIBS_libgit_GUID"};
my $uuid_xdiff_lib = $$build_structure{"LIBS_xdiff/lib_GUID"};
print F << "EOM";
<ItemGroup>
<ProjectReference Include="$cdup\\libgit\\libgit.vcxproj">
<Project>$uuid_libgit</Project>
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
</ProjectReference>
EOM
if (!($name =~ 'xdiff')) {
print F << "EOM";
<ProjectReference Include="$cdup\\xdiff\\lib\\xdiff_lib.vcxproj">
<Project>$uuid_xdiff_lib</Project>
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
</ProjectReference>
EOM
}
if ($name =~ /(test-(line-buffer|svn-fe)|^git-remote-testsvn)\.exe$/) {
my $uuid_vcs_svn_lib = $$build_structure{"LIBS_vcs-svn/lib_GUID"};
print F << "EOM";
<ProjectReference Include="$cdup\\vcs-svn\\lib\\vcs-svn_lib.vcxproj">
<Project>$uuid_vcs_svn_lib</Project>
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
</ProjectReference>
EOM
}
print F << "EOM";
</ItemGroup>
EOM
}
print F << "EOM";
<Import Project="\$(VCTargetsPath)\\Microsoft.Cpp.targets" />
EOM
if (!$static_library) {
print F << "EOM";
<Target Name="${target}_AfterBuild" AfterTargets="AfterBuild">
<ItemGroup>
<DLLsAndPDBs Include="\$(VCPKGBinDirectory)\\*.dll;\$(VCPKGBinDirectory)\\*.pdb" />
</ItemGroup>
<Copy SourceFiles="@(DLLsAndPDBs)" DestinationFolder="\$(OutDir)" SkipUnchangedFiles="true" UseHardlinksIfPossible="true" />
<MakeDir Directories="..\\templates\\blt\\branches" />
</Target>
EOM
}
if ($target eq 'git') {
print F " <Import Project=\"LinkOrCopyBuiltins.targets\" />\n";
}
print F << "EOM";
</Project>
EOM
close F;
}
sub createGlueProject {
my ($git_dir, $out_dir, $rel_dir, %build_structure) = @_;
print "Generate solutions file\n";
$rel_dir = "..\\$rel_dir";
$rel_dir =~ s/\//\\/g;
my $SLN_HEAD = "Microsoft Visual Studio Solution File, Format Version 11.00\n# Visual Studio 2010\n";
my $SLN_PRE = "Project(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = ";
my $SLN_POST = "\nEndProject\n";
my @libs = @{$build_structure{"LIBS"}};
my @tmp;
foreach (@libs) {
$_ =~ s/\.a//;
push(@tmp, $_);
}
@libs = @tmp;
my @apps = @{$build_structure{"APPS"}};
@tmp = ();
foreach (@apps) {
$_ =~ s/\.exe//;
if ($_ eq "git" ) {
unshift(@tmp, $_);
} else {
push(@tmp, $_);
}
}
@apps = @tmp;
open F, ">git.sln" || die "Could not open git.sln for writing!\n";
binmode F, ":crlf :utf8";
print F chr(0xFEFF);
print F "$SLN_HEAD";
foreach (@apps) {
my $appname = $_;
my $uuid = $build_structure{"APPS_${appname}_GUID"};
print F "$SLN_PRE";
my $vcxproj = $build_structure{"APPS_${appname}_VCXPROJ"};
$vcxproj =~ s/\//\\/g;
$appname =~ s/.*\///;
print F "\"${appname}\", \"${vcxproj}\", \"${uuid}\"";
print F "$SLN_POST";
}
foreach (@libs) {
my $libname = $_;
my $uuid = $build_structure{"LIBS_${libname}_GUID"};
print F "$SLN_PRE";
my $vcxproj = $build_structure{"LIBS_${libname}_VCXPROJ"};
$vcxproj =~ s/\//\\/g;
$libname =~ s/\//_/g;
print F "\"${libname}\", \"${vcxproj}\", \"${uuid}\"";
print F "$SLN_POST";
}
print F << "EOM";
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
EOM
print F << "EOM";
GlobalSection(ProjectConfigurationPlatforms) = postSolution
EOM
foreach (@apps) {
my $appname = $_;
my $uuid = $build_structure{"APPS_${appname}_GUID"};
print F "\t\t${uuid}.Debug|x64.ActiveCfg = Debug|x64\n";
print F "\t\t${uuid}.Debug|x64.Build.0 = Debug|x64\n";
print F "\t\t${uuid}.Debug|x86.ActiveCfg = Debug|Win32\n";
print F "\t\t${uuid}.Debug|x86.Build.0 = Debug|Win32\n";
print F "\t\t${uuid}.Release|x64.ActiveCfg = Release|x64\n";
print F "\t\t${uuid}.Release|x64.Build.0 = Release|x64\n";
print F "\t\t${uuid}.Release|x86.ActiveCfg = Release|Win32\n";
print F "\t\t${uuid}.Release|x86.Build.0 = Release|Win32\n";
}
foreach (@libs) {
my $libname = $_;
my $uuid = $build_structure{"LIBS_${libname}_GUID"};
print F "\t\t${uuid}.Debug|x64.ActiveCfg = Debug|x64\n";
print F "\t\t${uuid}.Debug|x64.Build.0 = Debug|x64\n";
print F "\t\t${uuid}.Debug|x86.ActiveCfg = Debug|Win32\n";
print F "\t\t${uuid}.Debug|x86.Build.0 = Debug|Win32\n";
print F "\t\t${uuid}.Release|x64.ActiveCfg = Release|x64\n";
print F "\t\t${uuid}.Release|x64.Build.0 = Release|x64\n";
print F "\t\t${uuid}.Release|x86.ActiveCfg = Release|Win32\n";
print F "\t\t${uuid}.Release|x86.Build.0 = Release|Win32\n";
}
print F << "EOM";
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal
EOM
close F;
}
1;

View File

@ -12,6 +12,7 @@ use File::Basename;
use File::Spec; use File::Spec;
use Cwd; use Cwd;
use Generators; use Generators;
use Text::ParseWords;
my (%build_structure, %compile_options, @makedry); my (%build_structure, %compile_options, @makedry);
my $out_dir = getcwd(); my $out_dir = getcwd();
@ -31,6 +32,7 @@ generate usage:
-g <GENERATOR> --gen <GENERATOR> Specify the buildsystem generator (default: $gen) -g <GENERATOR> --gen <GENERATOR> Specify the buildsystem generator (default: $gen)
Available: $genlist Available: $genlist
-o <PATH> --out <PATH> Specify output directory generation (default: .) -o <PATH> --out <PATH> Specify output directory generation (default: .)
--make-out <PATH> Write the output of GNU Make into a file
-i <FILE> --in <FILE> Specify input file, instead of running GNU Make -i <FILE> --in <FILE> Specify input file, instead of running GNU Make
-h,-? --help This help -h,-? --help This help
EOM EOM
@ -38,6 +40,7 @@ EOM
} }
# Parse command-line options # Parse command-line options
my $make_out;
while (@ARGV) { while (@ARGV) {
my $arg = shift @ARGV; my $arg = shift @ARGV;
if ("$arg" eq "-h" || "$arg" eq "--help" || "$arg" eq "-?") { if ("$arg" eq "-h" || "$arg" eq "--help" || "$arg" eq "-?") {
@ -45,6 +48,8 @@ while (@ARGV) {
exit(0); exit(0);
} elsif("$arg" eq "--out" || "$arg" eq "-o") { } elsif("$arg" eq "--out" || "$arg" eq "-o") {
$out_dir = shift @ARGV; $out_dir = shift @ARGV;
} elsif("$arg" eq "--make-out") {
$make_out = shift @ARGV;
} elsif("$arg" eq "--gen" || "$arg" eq "-g") { } elsif("$arg" eq "--gen" || "$arg" eq "-g") {
$gen = shift @ARGV; $gen = shift @ARGV;
} elsif("$arg" eq "--in" || "$arg" eq "-i") { } elsif("$arg" eq "--in" || "$arg" eq "-i") {
@ -52,6 +57,8 @@ while (@ARGV) {
open(F, "<$infile") || die "Couldn't open file $infile"; open(F, "<$infile") || die "Couldn't open file $infile";
@makedry = <F>; @makedry = <F>;
close(F); close(F);
} else {
die "Unknown option: " . $arg;
} }
} }
@ -72,7 +79,19 @@ Running GNU Make to figure out build structure...
EOM EOM
# Pipe a make --dry-run into a variable, if not already loaded from file # Pipe a make --dry-run into a variable, if not already loaded from file
@makedry = `cd $git_dir && make -n MSVC=1 V=1 2>/dev/null` if !@makedry; # Capture the make dry stderr to file for review (will be empty for a release build).
my $ErrsFile = "msvc-build-makedryerrors.txt";
@makedry = `make -C $git_dir -n MSVC=1 SKIP_VCPKG=1 V=1 2>$ErrsFile`
if !@makedry;
# test for an empty Errors file and remove it
unlink $ErrsFile if -f -z $ErrsFile;
if (defined $make_out) {
open OUT, ">" . $make_out;
print OUT @makedry;
close OUT;
}
# Parse the make output into usable info # Parse the make output into usable info
parseMakeOutput(); parseMakeOutput();
@ -140,6 +159,12 @@ sub parseMakeOutput
next; next;
} }
if ($text =~ /^(mkdir|msgfmt) /) {
# options to the Portable Object translations
# the line "mkdir ... && msgfmt ..." contains no linker options
next;
}
if($text =~ / -c /) { if($text =~ / -c /) {
# compilation # compilation
handleCompileLine($text, $line); handleCompileLine($text, $line);
@ -231,7 +256,7 @@ sub removeDuplicates
sub handleCompileLine sub handleCompileLine
{ {
my ($line, $lineno) = @_; my ($line, $lineno) = @_;
my @parts = split(' ', $line); my @parts = shellwords($line);
my $sourcefile; my $sourcefile;
shift(@parts); # ignore cmd shift(@parts); # ignore cmd
while (my $part = shift @parts) { while (my $part = shift @parts) {
@ -265,7 +290,7 @@ sub handleLibLine
my (@objfiles, @lflags, $libout, $part); my (@objfiles, @lflags, $libout, $part);
# kill cmd and rm 'prefix' # kill cmd and rm 'prefix'
$line =~ s/^rm -f .* && .* rcs //; $line =~ s/^rm -f .* && .* rcs //;
my @parts = split(' ', $line); my @parts = shellwords($line);
while ($part = shift @parts) { while ($part = shift @parts) {
if ($part =~ /^-/) { if ($part =~ /^-/) {
push(@lflags, $part); push(@lflags, $part);
@ -282,7 +307,7 @@ sub handleLibLine
# exit(1); # exit(1);
foreach (@objfiles) { foreach (@objfiles) {
my $sourcefile = $_; my $sourcefile = $_;
$sourcefile =~ s/\.o/.c/; $sourcefile =~ s/\.o$/.c/;
push(@sources, $sourcefile); push(@sources, $sourcefile);
push(@cflags, @{$compile_options{"${sourcefile}_CFLAGS"}}); push(@cflags, @{$compile_options{"${sourcefile}_CFLAGS"}});
push(@defines, @{$compile_options{"${sourcefile}_DEFINES"}}); push(@defines, @{$compile_options{"${sourcefile}_DEFINES"}});
@ -306,7 +331,7 @@ sub handleLinkLine
{ {
my ($line, $lineno) = @_; my ($line, $lineno) = @_;
my (@objfiles, @lflags, @libs, $appout, $part); my (@objfiles, @lflags, @libs, $appout, $part);
my @parts = split(' ', $line); my @parts = shellwords($line);
shift(@parts); # ignore cmd shift(@parts); # ignore cmd
while ($part = shift @parts) { while ($part = shift @parts) {
if ($part =~ /^-IGNORE/) { if ($part =~ /^-IGNORE/) {
@ -321,22 +346,32 @@ sub handleLinkLine
push(@libs, "libeay32.lib"); push(@libs, "libeay32.lib");
} elsif ("$part" eq "-lssl") { } elsif ("$part" eq "-lssl") {
push(@libs, "ssleay32.lib"); push(@libs, "ssleay32.lib");
} elsif ($part =~ /^-/) { } elsif ("$part" eq "-lcurl") {
push(@libs, "libcurl.lib");
} elsif ("$part" eq "-lexpat") {
push(@libs, "expat.lib");
} elsif ("$part" eq "-liconv") {
push(@libs, "libiconv.lib");
} elsif ($part =~ /^[-\/]/) {
push(@lflags, $part); push(@lflags, $part);
} elsif ($part =~ /\.(a|lib)$/) { } elsif ($part =~ /\.(a|lib)$/) {
$part =~ s/\.a$/.lib/; $part =~ s/\.a$/.lib/;
push(@libs, $part); push(@libs, $part);
} elsif ($part =~ /\.(o|obj)$/) { } elsif ($part eq 'invalidcontinue.obj') {
# ignore - known to MSVC
} elsif ($part =~ /\.o$/) {
push(@objfiles, $part); push(@objfiles, $part);
} elsif ($part =~ /\.obj$/) {
# do nothing, 'make' should not be producing .obj, only .o files
} else { } else {
die "Unhandled lib option @ line $lineno: $part"; die "Unhandled link option @ line $lineno: $part";
} }
} }
# print "AppOut: '$appout'\nLFlags: @lflags\nLibs : @libs\nOfiles: @objfiles\n"; # print "AppOut: '$appout'\nLFlags: @lflags\nLibs : @libs\nOfiles: @objfiles\n";
# exit(1); # exit(1);
foreach (@objfiles) { foreach (@objfiles) {
my $sourcefile = $_; my $sourcefile = $_;
$sourcefile =~ s/\.o/.c/; $sourcefile =~ s/\.o$/.c/;
push(@sources, $sourcefile); push(@sources, $sourcefile);
push(@cflags, @{$compile_options{"${sourcefile}_CFLAGS"}}); push(@cflags, @{$compile_options{"${sourcefile}_CFLAGS"}});
push(@defines, @{$compile_options{"${sourcefile}_DEFINES"}}); push(@defines, @{$compile_options{"${sourcefile}_DEFINES"}});

3
git.c
View File

@ -739,8 +739,6 @@ static int run_argv(int *argcp, const char ***argv)
*/ */
if (!done_alias) if (!done_alias)
handle_builtin(*argcp, *argv); handle_builtin(*argcp, *argv);
#if 0 // TODO In GFW, need to amend a7924b655e940b06cb547c235d6bed9767929673 to include trace2_ and _tr2 lines.
else if (get_builtin(**argv)) { else if (get_builtin(**argv)) {
struct argv_array args = ARGV_ARRAY_INIT; struct argv_array args = ARGV_ARRAY_INIT;
int i; int i;
@ -775,7 +773,6 @@ static int run_argv(int *argcp, const char ***argv)
exit(i); exit(i);
die("could not execute builtin %s", **argv); die("could not execute builtin %s", **argv);
} }
#endif // a7924b655e940b06cb547c235d6bed9767929673
/* .. then try the external ones */ /* .. then try the external ones */
execv_dashed_external(*argv); execv_dashed_external(*argv);

View File

@ -2863,7 +2863,8 @@ static int detect_and_process_renames(struct merge_options *opt,
head_pairs = get_diffpairs(opt, common, head); head_pairs = get_diffpairs(opt, common, head);
merge_pairs = get_diffpairs(opt, common, merge); merge_pairs = get_diffpairs(opt, common, merge);
if (opt->detect_directory_renames) { if ((opt->detect_directory_renames == 2) ||
(opt->detect_directory_renames == 1 && !opt->call_depth)) {
dir_re_head = get_directory_renames(head_pairs); dir_re_head = get_directory_renames(head_pairs);
dir_re_merge = get_directory_renames(merge_pairs); dir_re_merge = get_directory_renames(merge_pairs);

View File

@ -2151,8 +2151,10 @@ static struct ref_iterator *reflog_iterator_begin(struct ref_store *ref_store,
strbuf_addf(&sb, "%s/logs", gitdir); strbuf_addf(&sb, "%s/logs", gitdir);
diter = dir_iterator_begin(sb.buf, 0); diter = dir_iterator_begin(sb.buf, 0);
if(!diter) if (!diter) {
strbuf_release(&sb);
return empty_ref_iterator_begin(); return empty_ref_iterator_begin();
}
iter = xcalloc(1, sizeof(*iter)); iter = xcalloc(1, sizeof(*iter));
ref_iterator = &iter->base; ref_iterator = &iter->base;

View File

@ -799,6 +799,7 @@ static void read_alternate_refs(const char *path,
fclose(fh); fclose(fh);
finish_command(&cmd); finish_command(&cmd);
strbuf_release(&line);
} }
struct alternate_refs_data { struct alternate_refs_data {

View File

@ -4,13 +4,21 @@
#include "iterator.h" #include "iterator.h"
#include "dir-iterator.h" #include "dir-iterator.h"
static const char *error_name(int error_number)
{
switch (error_number) {
case ENOENT: return "ENOENT";
case ENOTDIR: return "ENOTDIR";
default: return "ESOMETHINGELSE";
}
}
/* /*
* usage: * usage:
* tool-test dir-iterator [--follow-symlinks] [--pedantic] directory_path * tool-test dir-iterator [--follow-symlinks] [--pedantic] directory_path
*/ */
int cmd__dir_iterator(int argc, const char **argv) int cmd__dir_iterator(int argc, const char **argv)
{ {
struct strbuf path = STRBUF_INIT;
struct dir_iterator *diter; struct dir_iterator *diter;
unsigned int flags = 0; unsigned int flags = 0;
int iter_status; int iter_status;
@ -27,11 +35,10 @@ int cmd__dir_iterator(int argc, const char **argv)
if (!*argv || argc != 1) if (!*argv || argc != 1)
die("dir-iterator needs exactly one non-option argument"); die("dir-iterator needs exactly one non-option argument");
strbuf_add(&path, *argv, strlen(*argv)); diter = dir_iterator_begin(*argv, flags);
diter = dir_iterator_begin(path.buf, flags);
if (!diter) { if (!diter) {
printf("dir_iterator_begin failure: %d\n", errno); printf("dir_iterator_begin failure: %s\n", error_name(errno));
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }

View File

@ -25,16 +25,14 @@ try_local_x () {
echo "$x" echo "$x"
} }
# This test is an experiment to check whether any Git users are using # Check whether the shell supports the "local" keyword. "local" is not
# Shells that don't support the "local" keyword. "local" is not
# POSIX-standard, but it is very widely supported by POSIX-compliant # POSIX-standard, but it is very widely supported by POSIX-compliant
# shells, and if it doesn't cause problems for people, we would like # shells, and we rely on it within Git's test framework.
# to be able to use it in Git code.
# #
# For now, this is the only test that requires "local". If your shell # If your shell fails this test, the results of other tests may be
# fails this test, you can ignore the failure, but please report the # unreliable. You may wish to report the problem to the Git mailing
# problem to the Git mailing list <git@vger.kernel.org>, as it might # list <git@vger.kernel.org>, as it could cause us to reconsider
# convince us to continue avoiding the use of "local". # relying on "local".
test_expect_success 'verify that the running shell supports "local"' ' test_expect_success 'verify that the running shell supports "local"' '
x="notlocal" && x="notlocal" &&
echo "local" >expected1 && echo "local" >expected1 &&

View File

@ -170,31 +170,45 @@ NULL
' '
test_expect_success 'iterate' ' test_expect_success 'iterate' '
test-tool hashmap >actual.raw <<-\EOF &&
put key1 value1
put key2 value2
put fooBarFrotz value3
iterate
EOF
test_hashmap "put key1 value1 cat >expect <<-\EOF &&
put key2 value2 NULL
put fooBarFrotz value3 NULL
iterate" "NULL NULL
NULL fooBarFrotz value3
NULL key1 value1
key2 value2 key2 value2
key1 value1 EOF
fooBarFrotz value3"
sort <actual.raw >actual &&
test_cmp expect actual
' '
test_expect_success 'iterate (case insensitive)' ' test_expect_success 'iterate (case insensitive)' '
test-tool hashmap ignorecase >actual.raw <<-\EOF &&
put key1 value1
put key2 value2
put fooBarFrotz value3
iterate
EOF
test_hashmap "put key1 value1 cat >expect <<-\EOF &&
put key2 value2 NULL
put fooBarFrotz value3 NULL
iterate" "NULL NULL
NULL fooBarFrotz value3
NULL key1 value1
fooBarFrotz value3 key2 value2
key2 value2 EOF
key1 value1" ignorecase
sort <actual.raw >actual &&
test_cmp expect actual
' '
test_expect_success 'grow / shrink' ' test_expect_success 'grow / shrink' '

View File

@ -86,17 +86,25 @@ NULL"
' '
test_expect_success 'iterate' ' test_expect_success 'iterate' '
test-tool oidmap >actual.raw <<-\EOF &&
put one 1
put two 2
put three 3
iterate
EOF
test_oidmap "put one 1 # sort "expect" too so we do not rely on the order of particular oids
put two 2 sort >expect <<-EOF &&
put three 3 NULL
iterate" "NULL NULL
NULL NULL
NULL $(git rev-parse one) 1
$(git rev-parse two) 2 $(git rev-parse two) 2
$(git rev-parse one) 1 $(git rev-parse three) 3
$(git rev-parse three) 3" EOF
sort <actual.raw >actual &&
test_cmp expect actual
' '
test_done test_done

View File

@ -15,8 +15,10 @@ compare_ws_file () {
pfx=$1 pfx=$1
exp=$2.expect exp=$2.expect
act=$pfx.actual.$3 act=$pfx.actual.$3
tr '\015\000abcdef0123456789' QN00000000000000000 <"$2" >"$exp" && tr '\015\000abcdef0123456789' QN00000000000000000 <"$2" |
tr '\015\000abcdef0123456789' QN00000000000000000 <"$3" >"$act" && sed -e "s/0000*/$ZERO_OID/" >"$exp" &&
tr '\015\000abcdef0123456789' QN00000000000000000 <"$3" |
sed -e "s/0000*/$ZERO_OID/" >"$act" &&
test_cmp "$exp" "$act" && test_cmp "$exp" "$act" &&
rm "$exp" "$act" rm "$exp" "$act"
} }

View File

@ -55,13 +55,13 @@ test_expect_success 'dir-iterator should list files in the correct order' '
test_expect_success 'begin should fail upon inexistent paths' ' test_expect_success 'begin should fail upon inexistent paths' '
test_must_fail test-tool dir-iterator ./inexistent-path \ test_must_fail test-tool dir-iterator ./inexistent-path \
>actual-inexistent-path-output && >actual-inexistent-path-output &&
echo "dir_iterator_begin failure: 2" >expected-inexistent-path-output && echo "dir_iterator_begin failure: ENOENT" >expected-inexistent-path-output &&
test_cmp expected-inexistent-path-output actual-inexistent-path-output test_cmp expected-inexistent-path-output actual-inexistent-path-output
' '
test_expect_success 'begin should fail upon non directory paths' ' test_expect_success 'begin should fail upon non directory paths' '
test_must_fail test-tool dir-iterator ./dir/b >actual-non-dir-output && test_must_fail test-tool dir-iterator ./dir/b >actual-non-dir-output &&
echo "dir_iterator_begin failure: 20" >expected-non-dir-output && echo "dir_iterator_begin failure: ENOTDIR" >expected-non-dir-output &&
test_cmp expected-non-dir-output actual-non-dir-output test_cmp expected-non-dir-output actual-non-dir-output
' '

View File

@ -162,8 +162,8 @@ test_expect_success PERL 'commit --interactive gives cache-tree on partial commi
' '
test_expect_success PERL 'commit -p with shrinking cache-tree' ' test_expect_success PERL 'commit -p with shrinking cache-tree' '
mkdir -p deep/subdir && mkdir -p deep/very-long-subdir &&
echo content >deep/subdir/file && echo content >deep/very-long-subdir/file &&
git add deep && git add deep &&
git commit -m add && git commit -m add &&
git rm -r deep && git rm -r deep &&

View File

@ -9,22 +9,19 @@ echo_without_newline() {
} }
test_blob_does_not_exist() { test_blob_does_not_exist() {
test_expect_success SHA1 'blob does not exist in database' " test_expect_success 'blob does not exist in database' "
test_must_fail git cat-file blob $1 test_must_fail git cat-file blob $1
" "
} }
test_blob_exists() { test_blob_exists() {
test_expect_success SHA1 'blob exists in database' " test_expect_success 'blob exists in database' "
git cat-file blob $1 git cat-file blob $1
" "
} }
hello_content="Hello World" hello_content="Hello World"
hello_sha1=5e1c309dae7f45e0f39b1bf3ac3cd9db12e7d689
example_content="This is an example" example_content="This is an example"
example_sha1=ddd3f836d3e3fbb7ae289aa9ae83536f76956399
setup_repo() { setup_repo() {
echo_without_newline "$hello_content" > hello echo_without_newline "$hello_content" > hello
@ -44,7 +41,16 @@ pop_repo() {
rm -rf $test_repo rm -rf $test_repo
} }
setup_repo test_expect_success 'setup' '
setup_repo &&
test_oid_cache <<-EOF
hello sha1:5e1c309dae7f45e0f39b1bf3ac3cd9db12e7d689
hello sha256:1e3b6c04d2eeb2b3e45c8a330445404c0b7cc7b257e2b097167d26f5230090c4
example sha1:ddd3f836d3e3fbb7ae289aa9ae83536f76956399
example sha256:b44fe1fe65589848253737db859bd490453510719d7424daab03daf0767b85ae
EOF
'
# Argument checking # Argument checking
@ -73,23 +79,23 @@ test_expect_success "Can't use --path with --no-filters" '
push_repo push_repo
test_expect_success SHA1 'hash a file' ' test_expect_success 'hash a file' '
test $hello_sha1 = $(git hash-object hello) test "$(test_oid hello)" = $(git hash-object hello)
' '
test_blob_does_not_exist $hello_sha1 test_blob_does_not_exist "$(test_oid hello)"
test_expect_success SHA1 'hash from stdin' ' test_expect_success 'hash from stdin' '
test $example_sha1 = $(git hash-object --stdin < example) test "$(test_oid example)" = $(git hash-object --stdin < example)
' '
test_blob_does_not_exist $example_sha1 test_blob_does_not_exist "$(test_oid example)"
test_expect_success SHA1 'hash a file and write to database' ' test_expect_success 'hash a file and write to database' '
test $hello_sha1 = $(git hash-object -w hello) test "$(test_oid hello)" = $(git hash-object -w hello)
' '
test_blob_exists $hello_sha1 test_blob_exists "$(test_oid hello)"
test_expect_success 'git hash-object --stdin file1 <file0 first operates on file0, then file1' ' test_expect_success 'git hash-object --stdin file1 <file0 first operates on file0, then file1' '
echo foo > file1 && echo foo > file1 &&
@ -161,11 +167,11 @@ pop_repo
for args in "-w --stdin" "--stdin -w"; do for args in "-w --stdin" "--stdin -w"; do
push_repo push_repo
test_expect_success SHA1 "hash from stdin and write to database ($args)" ' test_expect_success "hash from stdin and write to database ($args)" '
test $example_sha1 = $(git hash-object $args < example) test "$(test_oid example)" = $(git hash-object $args < example)
' '
test_blob_exists $example_sha1 test_blob_exists "$(test_oid example)"
pop_repo pop_repo
done done
@ -173,22 +179,22 @@ done
filenames="hello filenames="hello
example" example"
sha1s="$hello_sha1 oids="$(test_oid hello)
$example_sha1" $(test_oid example)"
test_expect_success SHA1 "hash two files with names on stdin" ' test_expect_success "hash two files with names on stdin" '
test "$sha1s" = "$(echo_without_newline "$filenames" | git hash-object --stdin-paths)" test "$oids" = "$(echo_without_newline "$filenames" | git hash-object --stdin-paths)"
' '
for args in "-w --stdin-paths" "--stdin-paths -w"; do for args in "-w --stdin-paths" "--stdin-paths -w"; do
push_repo push_repo
test_expect_success SHA1 "hash two files with names on stdin and write to database ($args)" ' test_expect_success "hash two files with names on stdin and write to database ($args)" '
test "$sha1s" = "$(echo_without_newline "$filenames" | git hash-object $args)" test "$oids" = "$(echo_without_newline "$filenames" | git hash-object $args)"
' '
test_blob_exists $hello_sha1 test_blob_exists "$(test_oid hello)"
test_blob_exists $example_sha1 test_blob_exists "$(test_oid example)"
pop_repo pop_repo
done done

View File

@ -89,4 +89,9 @@ test_expect_failure 'ignore .git/ with invalid config' '
test_with_config "[" test_with_config "["
' '
test_expect_success 'early config and onbranch' '
echo "[broken" >broken &&
test_with_config "[includeif \"onbranch:refs/heads/master\"]path=../broken"
'
test_done test_done

View File

@ -30,14 +30,13 @@ check_fsck () {
} }
corrupt () { corrupt () {
aa=${1%??????????????????????????????????????} zz=${1#??} mv .git/objects/$(test_oid_to_path $1) .git/$1
mv .git/objects/$aa/$zz .git/$aa$zz
} }
recover () { recover () {
aa=${1%??????????????????????????????????????} zz=${1#??} aa=$(echo $1 | cut -c 1-2)
mkdir -p .git/objects/$aa mkdir -p .git/objects/$aa
mv .git/$aa$zz .git/objects/$aa/$zz mv .git/$1 .git/objects/$(test_oid_to_path $1)
} }
check_dont_have () { check_dont_have () {
@ -55,6 +54,7 @@ check_dont_have () {
} }
test_expect_success setup ' test_expect_success setup '
test_oid_init &&
mkdir -p A/B && mkdir -p A/B &&
echo rat >C && echo rat >C &&
echo ox >A/D && echo ox >A/D &&
@ -313,12 +313,12 @@ test_expect_success 'stale dirs do not cause d/f conflicts (reflogs off)' '
# Each line is 114 characters, so we need 75 to still have a few before the # Each line is 114 characters, so we need 75 to still have a few before the
# last 8K. The 89-character padding on the final entry lines up our # last 8K. The 89-character padding on the final entry lines up our
# newline exactly. # newline exactly.
test_expect_success 'parsing reverse reflogs at BUFSIZ boundaries' ' test_expect_success SHA1 'parsing reverse reflogs at BUFSIZ boundaries' '
git checkout -b reflogskip && git checkout -b reflogskip &&
z38=00000000000000000000000000000000000000 && zf=$(test_oid zero_2) &&
ident="abc <xyz> 0000000001 +0000" && ident="abc <xyz> 0000000001 +0000" &&
for i in $(test_seq 1 75); do for i in $(test_seq 1 75); do
printf "$z38%02d $z38%02d %s\t" $i $(($i+1)) "$ident" && printf "$zf%02d $zf%02d %s\t" $i $(($i+1)) "$ident" &&
if test $i = 75; then if test $i = 75; then
for j in $(test_seq 1 89); do for j in $(test_seq 1 89); do
printf X printf X
@ -329,7 +329,7 @@ test_expect_success 'parsing reverse reflogs at BUFSIZ boundaries' '
printf "\n" printf "\n"
done >.git/logs/refs/heads/reflogskip && done >.git/logs/refs/heads/reflogskip &&
git rev-parse reflogskip@{73} >actual && git rev-parse reflogskip@{73} >actual &&
echo ${z38}03 >expect && echo ${zf}03 >expect &&
test_cmp expect actual test_cmp expect actual
' '

View File

@ -9,6 +9,7 @@ test_description='git fsck random collection of tests
. ./test-lib.sh . ./test-lib.sh
test_expect_success setup ' test_expect_success setup '
test_oid_init &&
git config gc.auto 0 && git config gc.auto 0 &&
git config i18n.commitencoding ISO-8859-1 && git config i18n.commitencoding ISO-8859-1 &&
test_commit A fileA one && test_commit A fileA one &&
@ -54,8 +55,8 @@ test_expect_success 'setup: helpers for corruption tests' '
test_expect_success 'object with bad sha1' ' test_expect_success 'object with bad sha1' '
sha=$(echo blob | git hash-object -w --stdin) && sha=$(echo blob | git hash-object -w --stdin) &&
old=$(echo $sha | sed "s+^..+&/+") && old=$(test_oid_to_path "$sha") &&
new=$(dirname $old)/ffffffffffffffffffffffffffffffffffffff && new=$(dirname $old)/$(test_oid ff_2) &&
sha="$(dirname $new)$(basename $new)" && sha="$(dirname $new)$(basename $new)" &&
mv .git/objects/$old .git/objects/$new && mv .git/objects/$old .git/objects/$new &&
test_when_finished "remove_object $sha" && test_when_finished "remove_object $sha" &&
@ -84,7 +85,7 @@ test_expect_success 'branch pointing to non-commit' '
test_expect_success 'HEAD link pointing at a funny object' ' test_expect_success 'HEAD link pointing at a funny object' '
test_when_finished "mv .git/SAVED_HEAD .git/HEAD" && test_when_finished "mv .git/SAVED_HEAD .git/HEAD" &&
mv .git/HEAD .git/SAVED_HEAD && mv .git/HEAD .git/SAVED_HEAD &&
echo 0000000000000000000000000000000000000000 >.git/HEAD && echo $ZERO_OID >.git/HEAD &&
# avoid corrupt/broken HEAD from interfering with repo discovery # avoid corrupt/broken HEAD from interfering with repo discovery
test_must_fail env GIT_DIR=.git git fsck 2>out && test_must_fail env GIT_DIR=.git git fsck 2>out &&
cat out && cat out &&
@ -244,10 +245,16 @@ test_expect_success 'tree object with duplicate entries' '
' '
test_expect_success 'unparseable tree object' ' test_expect_success 'unparseable tree object' '
test_oid_cache <<-\EOF &&
junk sha1:twenty-bytes-of-junk
junk sha256:twenty-bytes-of-junk-twelve-more
EOF
test_when_finished "git update-ref -d refs/heads/wrong" && test_when_finished "git update-ref -d refs/heads/wrong" &&
test_when_finished "remove_object \$tree_sha1" && test_when_finished "remove_object \$tree_sha1" &&
test_when_finished "remove_object \$commit_sha1" && test_when_finished "remove_object \$commit_sha1" &&
tree_sha1=$(printf "100644 \0twenty-bytes-of-junk" | git hash-object -t tree --stdin -w --literally) && junk=$(test_oid junk) &&
tree_sha1=$(printf "100644 \0$junk" | git hash-object -t tree --stdin -w --literally) &&
commit_sha1=$(git commit-tree $tree_sha1) && commit_sha1=$(git commit-tree $tree_sha1) &&
git update-ref refs/heads/wrong $commit_sha1 && git update-ref refs/heads/wrong $commit_sha1 &&
test_must_fail git fsck 2>out && test_must_fail git fsck 2>out &&
@ -275,8 +282,9 @@ test_expect_success 'tree entry with type mismatch' '
' '
test_expect_success 'tag pointing to nonexistent' ' test_expect_success 'tag pointing to nonexistent' '
cat >invalid-tag <<-\EOF && badoid=$(test_oid deadbeef) &&
object ffffffffffffffffffffffffffffffffffffffff cat >invalid-tag <<-EOF &&
object $badoid
type commit type commit
tag invalid tag invalid
tagger T A Gger <tagger@example.com> 1234567890 -0000 tagger T A Gger <tagger@example.com> 1234567890 -0000
@ -386,8 +394,8 @@ test_expect_success 'rev-list --verify-objects' '
test_expect_success 'rev-list --verify-objects with bad sha1' ' test_expect_success 'rev-list --verify-objects with bad sha1' '
sha=$(echo blob | git hash-object -w --stdin) && sha=$(echo blob | git hash-object -w --stdin) &&
old=$(echo $sha | sed "s+^..+&/+") && old=$(test_oid_to_path $sha) &&
new=$(dirname $old)/ffffffffffffffffffffffffffffffffffffff && new=$(dirname $old)/$(test_oid ff_2) &&
sha="$(dirname $new)$(basename $new)" && sha="$(dirname $new)$(basename $new)" &&
mv .git/objects/$old .git/objects/$new && mv .git/objects/$old .git/objects/$new &&
test_when_finished "remove_object $sha" && test_when_finished "remove_object $sha" &&
@ -402,7 +410,7 @@ test_expect_success 'rev-list --verify-objects with bad sha1' '
test_might_fail git rev-list --verify-objects refs/heads/bogus >/dev/null 2>out && test_might_fail git rev-list --verify-objects refs/heads/bogus >/dev/null 2>out &&
cat out && cat out &&
test_i18ngrep -q "error: hash mismatch 63ffffffffffffffffffffffffffffffffffffff" out test_i18ngrep -q "error: hash mismatch $(dirname $new)$(test_oid ff_2)" out
' '
test_expect_success 'force fsck to ignore double author' ' test_expect_success 'force fsck to ignore double author' '
@ -417,13 +425,12 @@ test_expect_success 'force fsck to ignore double author' '
' '
_bz='\0' _bz='\0'
_bz5="$_bz$_bz$_bz$_bz$_bz" _bzoid=$(printf $ZERO_OID | sed -e 's/00/\\0/g')
_bz20="$_bz5$_bz5$_bz5$_bz5"
test_expect_success 'fsck notices blob entry pointing to null sha1' ' test_expect_success 'fsck notices blob entry pointing to null sha1' '
(git init null-blob && (git init null-blob &&
cd null-blob && cd null-blob &&
sha=$(printf "100644 file$_bz$_bz20" | sha=$(printf "100644 file$_bz$_bzoid" |
git hash-object -w --stdin -t tree) && git hash-object -w --stdin -t tree) &&
git fsck 2>out && git fsck 2>out &&
cat out && cat out &&
@ -434,7 +441,7 @@ test_expect_success 'fsck notices blob entry pointing to null sha1' '
test_expect_success 'fsck notices submodule entry pointing to null sha1' ' test_expect_success 'fsck notices submodule entry pointing to null sha1' '
(git init null-commit && (git init null-commit &&
cd null-commit && cd null-commit &&
sha=$(printf "160000 submodule$_bz$_bz20" | sha=$(printf "160000 submodule$_bz$_bzoid" |
git hash-object -w --stdin -t tree) && git hash-object -w --stdin -t tree) &&
git fsck 2>out && git fsck 2>out &&
cat out && cat out &&
@ -586,7 +593,7 @@ test_expect_success 'fsck --connectivity-only' '
# its type. That lets us see that --connectivity-only is # its type. That lets us see that --connectivity-only is
# not actually looking at the contents, but leaves it # not actually looking at the contents, but leaves it
# free to examine the type if it chooses. # free to examine the type if it chooses.
empty=.git/objects/e6/9de29bb2d1d6434b8b29ae775ad8c2e48c5391 && empty=.git/objects/$(test_oid_to_path $EMPTY_BLOB) &&
blob=$(echo unrelated | git hash-object -w --stdin) && blob=$(echo unrelated | git hash-object -w --stdin) &&
mv -f $(sha1_file $blob) $empty && mv -f $(sha1_file $blob) $empty &&
@ -631,10 +638,12 @@ test_expect_success 'fsck --name-objects' '
test_expect_success 'alternate objects are correctly blamed' ' test_expect_success 'alternate objects are correctly blamed' '
test_when_finished "rm -rf alt.git .git/objects/info/alternates" && test_when_finished "rm -rf alt.git .git/objects/info/alternates" &&
name=$(test_oid numeric) &&
path=$(test_oid_to_path "$name") &&
git init --bare alt.git && git init --bare alt.git &&
echo "../../alt.git/objects" >.git/objects/info/alternates && echo "../../alt.git/objects" >.git/objects/info/alternates &&
mkdir alt.git/objects/12 && mkdir alt.git/objects/$(dirname $path) &&
>alt.git/objects/12/34567890123456789012345678901234567890 && >alt.git/objects/$(dirname $path)/$(basename $path) &&
test_must_fail git fsck >out 2>&1 && test_must_fail git fsck >out 2>&1 &&
test_i18ngrep alt.git out test_i18ngrep alt.git out
' '

View File

@ -20,6 +20,22 @@ create_non_racy_file () {
test-tool chmtime =-5 "$1" test-tool chmtime =-5 "$1"
} }
test_expect_success 'setup' '
test_oid_cache <<-EOF
own_v3 sha1:8299b0bcd1ac364e5f1d7768efb62fa2da79a339
own_v3 sha256:38a6d2925e3eceec33ad7b34cbff4e0086caa0daf28f31e51f5bd94b4a7af86b
base_v3 sha1:39d890139ee5356c7ef572216cebcd27aa41f9df
base_v3 sha256:c9baeadf905112bf6c17aefbd7d02267afd70ded613c30cafed2d40cb506e1ed
own_v4 sha1:432ef4b63f32193984f339431fd50ca796493569
own_v4 sha256:6738ac6319c25b694afa7bcc313deb182d1a59b68bf7a47b4296de83478c0420
base_v4 sha1:508851a7f0dfa8691e9f69c7f055865389012491
base_v4 sha256:3177d4adfdd4b6904f7e921d91d715a471c0dde7cf6a4bba574927f02b699508
EOF
'
test_expect_success 'enable split index' ' test_expect_success 'enable split index' '
git config splitIndex.maxPercentChange 100 && git config splitIndex.maxPercentChange 100 &&
git update-index --split-index && git update-index --split-index &&
@ -29,11 +45,11 @@ test_expect_success 'enable split index' '
# NEEDSWORK: Stop hard-coding checksums. # NEEDSWORK: Stop hard-coding checksums.
if test "$indexversion" = "4" if test "$indexversion" = "4"
then then
own=432ef4b63f32193984f339431fd50ca796493569 own=$(test_oid own_v4)
base=508851a7f0dfa8691e9f69c7f055865389012491 base=$(test_oid base_v4)
else else
own=8299b0bcd1ac364e5f1d7768efb62fa2da79a339 own=$(test_oid own_v3)
base=39d890139ee5356c7ef572216cebcd27aa41f9df base=$(test_oid base_v3)
fi && fi &&
cat >expect <<-EOF && cat >expect <<-EOF &&
@ -99,17 +115,18 @@ test_expect_success 'enable split index again, "one" now belongs to base index"'
test_expect_success 'modify original file, base index untouched' ' test_expect_success 'modify original file, base index untouched' '
echo modified | create_non_racy_file one && echo modified | create_non_racy_file one &&
file1_blob=$(git hash-object one) &&
git update-index one && git update-index one &&
git ls-files --stage >ls-files.actual && git ls-files --stage >ls-files.actual &&
cat >ls-files.expect <<-EOF && cat >ls-files.expect <<-EOF &&
100644 2e0996000b7e9019eabcad29391bf0f5c7702f0b 0 one 100644 $file1_blob 0 one
EOF EOF
test_cmp ls-files.expect ls-files.actual && test_cmp ls-files.expect ls-files.actual &&
test-tool dump-split-index .git/index | sed "/^own/d" >actual && test-tool dump-split-index .git/index | sed "/^own/d" >actual &&
q_to_tab >expect <<-EOF && q_to_tab >expect <<-EOF &&
$BASE $BASE
100644 2e0996000b7e9019eabcad29391bf0f5c7702f0b 0Q 100644 $file1_blob 0Q
replacements: 0 replacements: 0
deletions: deletions:
EOF EOF
@ -121,7 +138,7 @@ test_expect_success 'add another file, which stays index' '
git update-index --add two && git update-index --add two &&
git ls-files --stage >ls-files.actual && git ls-files --stage >ls-files.actual &&
cat >ls-files.expect <<-EOF && cat >ls-files.expect <<-EOF &&
100644 2e0996000b7e9019eabcad29391bf0f5c7702f0b 0 one 100644 $file1_blob 0 one
100644 $EMPTY_BLOB 0 two 100644 $EMPTY_BLOB 0 two
EOF EOF
test_cmp ls-files.expect ls-files.actual && test_cmp ls-files.expect ls-files.actual &&
@ -129,7 +146,7 @@ test_expect_success 'add another file, which stays index' '
test-tool dump-split-index .git/index | sed "/^own/d" >actual && test-tool dump-split-index .git/index | sed "/^own/d" >actual &&
q_to_tab >expect <<-EOF && q_to_tab >expect <<-EOF &&
$BASE $BASE
100644 2e0996000b7e9019eabcad29391bf0f5c7702f0b 0Q 100644 $file1_blob 0Q
100644 $EMPTY_BLOB 0 two 100644 $EMPTY_BLOB 0 two
replacements: 0 replacements: 0
deletions: deletions:
@ -141,14 +158,14 @@ test_expect_success 'remove file not in base index' '
git update-index --force-remove two && git update-index --force-remove two &&
git ls-files --stage >ls-files.actual && git ls-files --stage >ls-files.actual &&
cat >ls-files.expect <<-EOF && cat >ls-files.expect <<-EOF &&
100644 2e0996000b7e9019eabcad29391bf0f5c7702f0b 0 one 100644 $file1_blob 0 one
EOF EOF
test_cmp ls-files.expect ls-files.actual && test_cmp ls-files.expect ls-files.actual &&
test-tool dump-split-index .git/index | sed "/^own/d" >actual && test-tool dump-split-index .git/index | sed "/^own/d" >actual &&
q_to_tab >expect <<-EOF && q_to_tab >expect <<-EOF &&
$BASE $BASE
100644 2e0996000b7e9019eabcad29391bf0f5c7702f0b 0Q 100644 $file1_blob 0Q
replacements: 0 replacements: 0
deletions: deletions:
EOF EOF
@ -237,9 +254,9 @@ test_expect_success 'set core.splitIndex config variable to true' '
git update-index --add three && git update-index --add three &&
git ls-files --stage >ls-files.actual && git ls-files --stage >ls-files.actual &&
cat >ls-files.expect <<-EOF && cat >ls-files.expect <<-EOF &&
100644 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 0 one 100644 $EMPTY_BLOB 0 one
100644 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 0 three 100644 $EMPTY_BLOB 0 three
100644 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 0 two 100644 $EMPTY_BLOB 0 two
EOF EOF
test_cmp ls-files.expect ls-files.actual && test_cmp ls-files.expect ls-files.actual &&
BASE=$(test-tool dump-split-index .git/index | grep "^base") && BASE=$(test-tool dump-split-index .git/index | grep "^base") &&
@ -257,8 +274,8 @@ test_expect_success 'set core.splitIndex config variable to false' '
git update-index --force-remove three && git update-index --force-remove three &&
git ls-files --stage >ls-files.actual && git ls-files --stage >ls-files.actual &&
cat >ls-files.expect <<-EOF && cat >ls-files.expect <<-EOF &&
100644 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 0 one 100644 $EMPTY_BLOB 0 one
100644 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 0 two 100644 $EMPTY_BLOB 0 two
EOF EOF
test_cmp ls-files.expect ls-files.actual && test_cmp ls-files.expect ls-files.actual &&
test-tool dump-split-index .git/index | sed "/^own/d" >actual && test-tool dump-split-index .git/index | sed "/^own/d" >actual &&
@ -285,7 +302,7 @@ test_expect_success 'set core.splitIndex config variable back to true' '
test-tool dump-split-index .git/index | sed "/^own/d" >actual && test-tool dump-split-index .git/index | sed "/^own/d" >actual &&
cat >expect <<-EOF && cat >expect <<-EOF &&
$BASE $BASE
100644 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 0 four 100644 $EMPTY_BLOB 0 four
replacements: replacements:
deletions: deletions:
EOF EOF
@ -309,7 +326,7 @@ test_expect_success 'check behavior with splitIndex.maxPercentChange unset' '
test-tool dump-split-index .git/index | sed "/^own/d" >actual && test-tool dump-split-index .git/index | sed "/^own/d" >actual &&
cat >expect <<-EOF && cat >expect <<-EOF &&
$BASE $BASE
100644 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 0 six 100644 $EMPTY_BLOB 0 six
replacements: replacements:
deletions: deletions:
EOF EOF

View File

@ -247,12 +247,14 @@ test_expect_success 'diff-files/diff-cached shows ita as new/not-new files' '
test_expect_success '"diff HEAD" includes ita as new files' ' test_expect_success '"diff HEAD" includes ita as new files' '
git reset --hard && git reset --hard &&
echo new >new-ita && echo new >new-ita &&
oid=$(git hash-object new-ita) &&
oid=$(git rev-parse --short $oid) &&
git add -N new-ita && git add -N new-ita &&
git diff HEAD >actual && git diff HEAD >actual &&
cat >expected <<-\EOF && cat >expected <<-EOF &&
diff --git a/new-ita b/new-ita diff --git a/new-ita b/new-ita
new file mode 100644 new file mode 100644
index 0000000..3e75765 index 0000000..$oid
--- /dev/null --- /dev/null
+++ b/new-ita +++ b/new-ita
@@ -0,0 +1 @@ @@ -0,0 +1 @@

View File

@ -442,6 +442,34 @@ test_expect_success 'Log output with log.mailmap' '
test_cmp expect actual test_cmp expect actual
' '
test_expect_success 'log.mailmap=false disables mailmap' '
cat >expect <<-\EOF &&
Author: CTO <cto@coompany.xx>
Author: claus <me@company.xx>
Author: santa <me@company.xx>
Author: nick2 <nick2@company.xx>
Author: nick2 <bugs@company.xx>
Author: nick1 <bugs@company.xx>
Author: A U Thor <author@example.com>
EOF
git -c log.mailmap=False log | grep Author > actual &&
test_cmp expect actual
'
test_expect_success '--no-use-mailmap disables mailmap' '
cat >expect <<-\EOF &&
Author: CTO <cto@coompany.xx>
Author: claus <me@company.xx>
Author: santa <me@company.xx>
Author: nick2 <nick2@company.xx>
Author: nick2 <bugs@company.xx>
Author: nick1 <bugs@company.xx>
Author: A U Thor <author@example.com>
EOF
git log --no-use-mailmap | grep Author > actual &&
test_cmp expect actual
'
cat >expect <<\EOF cat >expect <<\EOF
Author: Santa Claus <santa.claus@northpole.xx> Author: Santa Claus <santa.claus@northpole.xx>
Author: Santa Claus <santa.claus@northpole.xx> Author: Santa Claus <santa.claus@northpole.xx>
@ -461,6 +489,11 @@ test_expect_success 'Grep author with log.mailmap' '
test_cmp expect actual test_cmp expect actual
' '
test_expect_success 'log.mailmap is true by default these days' '
git log --author Santa | grep Author >actual &&
test_cmp expect actual
'
test_expect_success 'Only grep replaced author with --use-mailmap' ' test_expect_success 'Only grep replaced author with --use-mailmap' '
git log --use-mailmap --author "<cto@coompany.xx>" >actual && git log --use-mailmap --author "<cto@coompany.xx>" >actual &&
test_must_be_empty actual test_must_be_empty actual

View File

@ -94,6 +94,13 @@ check_tar() {
' '
} }
test_expect_success 'setup' '
test_oid_cache <<-EOF
obj sha1:19f9c8273ec45a8938e6999cb59b3ff66739902a
obj sha256:3c666f798798601571f5cec0adb57ce4aba8546875e7693177e0535f34d2c49b
EOF
'
test_expect_success \ test_expect_success \
'populate workdir' \ 'populate workdir' \
'mkdir a && 'mkdir a &&
@ -369,11 +376,10 @@ test_lazy_prereq TAR_HUGE '
' '
test_expect_success LONG_IS_64BIT 'set up repository with huge blob' ' test_expect_success LONG_IS_64BIT 'set up repository with huge blob' '
obj_d=19 && obj=$(test_oid obj) &&
obj_f=f9c8273ec45a8938e6999cb59b3ff66739902a && path=$(test_oid_to_path $obj) &&
obj=${obj_d}${obj_f} && mkdir -p .git/objects/$(dirname $path) &&
mkdir -p .git/objects/$obj_d && cp "$TEST_DIRECTORY"/t5000/huge-object .git/objects/$path &&
cp "$TEST_DIRECTORY"/t5000/$obj .git/objects/$obj_d/$obj_f &&
rm -f .git/index && rm -f .git/index &&
git update-index --add --cacheinfo 100644,$obj,huge && git update-index --add --cacheinfo 100644,$obj,huge &&
git commit -m huge git commit -m huge

View File

@ -319,7 +319,9 @@ test_expect_success 'add octopus merge' '
git merge commits/3 commits/4 && git merge commits/3 commits/4 &&
git branch merge/octopus && git branch merge/octopus &&
git commit-graph write --reachable --split && git commit-graph write --reachable --split &&
git commit-graph verify && git commit-graph verify 2>err &&
test_line_count = 3 err &&
test_i18ngrep ! warning err &&
test_line_count = 3 $graphdir/commit-graph-chain test_line_count = 3 $graphdir/commit-graph-chain
' '

View File

@ -615,6 +615,7 @@ test_expect_success 'broken branch creation' '
git add missing/MISSING && git add missing/MISSING &&
git commit -m "6(broken): Added file that will be deleted" && git commit -m "6(broken): Added file that will be deleted" &&
git tag BROKEN_HASH6 && git tag BROKEN_HASH6 &&
deleted=$(git rev-parse --verify HEAD:missing) &&
add_line_into_file "7(broken): second line on a broken branch" hello2 && add_line_into_file "7(broken): second line on a broken branch" hello2 &&
git tag BROKEN_HASH7 && git tag BROKEN_HASH7 &&
add_line_into_file "8(broken): third line on a broken branch" hello2 && add_line_into_file "8(broken): third line on a broken branch" hello2 &&
@ -622,12 +623,12 @@ test_expect_success 'broken branch creation' '
git rm missing/MISSING && git rm missing/MISSING &&
git commit -m "9(broken): Remove missing file" && git commit -m "9(broken): Remove missing file" &&
git tag BROKEN_HASH9 && git tag BROKEN_HASH9 &&
rm .git/objects/39/f7e61a724187ab767d2e08442d9b6b9dab587d rm .git/objects/$(test_oid_to_path $deleted)
' '
echo "" > expected.ok echo "" > expected.ok
cat > expected.missing-tree.default <<EOF cat > expected.missing-tree.default <<EOF
fatal: unable to read tree 39f7e61a724187ab767d2e08442d9b6b9dab587d fatal: unable to read tree $deleted
EOF EOF
test_expect_success 'bisect fails if tree is broken on start commit' ' test_expect_success 'bisect fails if tree is broken on start commit' '
@ -713,12 +714,12 @@ test_expect_success 'bisect: demonstrate identification of damage boundary' "
" "
cat > expected.bisect-log <<EOF cat > expected.bisect-log <<EOF
# bad: [32a594a3fdac2d57cf6d02987e30eec68511498c] Add <4: Ciao for now> into <hello>. # bad: [$HASH4] Add <4: Ciao for now> into <hello>.
# good: [7b7f204a749c3125d5224ed61ea2ae1187ad046f] Add <2: A new day for git> into <hello>. # good: [$HASH2] Add <2: A new day for git> into <hello>.
git bisect start '32a594a3fdac2d57cf6d02987e30eec68511498c' '7b7f204a749c3125d5224ed61ea2ae1187ad046f' git bisect start '$HASH4' '$HASH2'
# good: [3de952f2416b6084f557ec417709eac740c6818c] Add <3: Another new day for git> into <hello>. # good: [$HASH3] Add <3: Another new day for git> into <hello>.
git bisect good 3de952f2416b6084f557ec417709eac740c6818c git bisect good $HASH3
# first bad commit: [32a594a3fdac2d57cf6d02987e30eec68511498c] Add <4: Ciao for now> into <hello>. # first bad commit: [$HASH4] Add <4: Ciao for now> into <hello>.
EOF EOF
test_expect_success 'bisect log: successful result' ' test_expect_success 'bisect log: successful result' '
@ -731,14 +732,14 @@ test_expect_success 'bisect log: successful result' '
' '
cat > expected.bisect-skip-log <<EOF cat > expected.bisect-skip-log <<EOF
# bad: [32a594a3fdac2d57cf6d02987e30eec68511498c] Add <4: Ciao for now> into <hello>. # bad: [$HASH4] Add <4: Ciao for now> into <hello>.
# good: [7b7f204a749c3125d5224ed61ea2ae1187ad046f] Add <2: A new day for git> into <hello>. # good: [$HASH2] Add <2: A new day for git> into <hello>.
git bisect start '32a594a3fdac2d57cf6d02987e30eec68511498c' '7b7f204a749c3125d5224ed61ea2ae1187ad046f' git bisect start '$HASH4' '$HASH2'
# skip: [3de952f2416b6084f557ec417709eac740c6818c] Add <3: Another new day for git> into <hello>. # skip: [$HASH3] Add <3: Another new day for git> into <hello>.
git bisect skip 3de952f2416b6084f557ec417709eac740c6818c git bisect skip $HASH3
# only skipped commits left to test # only skipped commits left to test
# possible first bad commit: [32a594a3fdac2d57cf6d02987e30eec68511498c] Add <4: Ciao for now> into <hello>. # possible first bad commit: [$HASH4] Add <4: Ciao for now> into <hello>.
# possible first bad commit: [3de952f2416b6084f557ec417709eac740c6818c] Add <3: Another new day for git> into <hello>. # possible first bad commit: [$HASH3] Add <3: Another new day for git> into <hello>.
EOF EOF
test_expect_success 'bisect log: only skip commits left' ' test_expect_success 'bisect log: only skip commits left' '

View File

@ -4403,4 +4403,115 @@ test_expect_success '13d-check(info): messages for rename/rename(1to1) via dual
) )
' '
# Testcase 13e, directory rename in virtual merge base
#
# This testcase has a slightly different setup than all the above cases, in
# order to include a recursive case:
#
# A C
# o - o
# / \ / \
# O o X ?
# \ / \ /
# o o
# B D
#
# Commit O: a/{z,y}
# Commit A: b/{z,y}
# Commit B: a/{z,y,x}
# Commit C: b/{z,y,x}
# Commit D: b/{z,y}, a/x
# Expected: b/{z,y,x} (sort of; see below for why this might not be expected)
#
# NOTES: 'X' represents a virtual merge base. With the default of
# directory rename detection yielding conflicts, merging A and B
# results in a conflict complaining about whether 'x' should be
# under 'a/' or 'b/'. However, when creating the virtual merge
# base 'X', since virtual merge bases need to be written out as a
# tree, we cannot have a conflict, so some resolution has to be
# picked.
#
# In choosing the right resolution, it's worth noting here that
# commits C & D are merges of A & B that choose different
# locations for 'x' (i.e. they resolve the conflict differently),
# and so it would be nice when merging C & D if git could detect
# this difference of opinion and report a conflict. But the only
# way to do so that I can think of would be to have the virtual
# merge base place 'x' in some directory other than either 'a/' or
# 'b/', which seems a little weird -- especially since it'd result
# in a rename/rename(1to2) conflict with a source path that never
# existed in any version.
#
# So, for now, when directory rename detection is set to
# 'conflict' just avoid doing directory rename detection at all in
# the recursive case. This will not allow us to detect a conflict
# in the outer merge for this special kind of setup, but it at
# least avoids hitting a BUG().
#
test_expect_success '13e-setup: directory rename detection in recursive case' '
test_create_repo 13e &&
(
cd 13e &&
mkdir a &&
echo z >a/z &&
echo y >a/y &&
git add a &&
test_tick &&
git commit -m "O" &&
git branch O &&
git branch A &&
git branch B &&
git checkout A &&
git mv a/ b/ &&
test_tick &&
git commit -m "A" &&
git checkout B &&
echo x >a/x &&
git add a &&
test_tick &&
git commit -m "B" &&
git branch C A &&
git branch D B &&
git checkout C &&
test_must_fail git -c merge.directoryRenames=conflict merge B &&
git add b/x &&
test_tick &&
git commit -m "C" &&
git checkout D &&
test_must_fail git -c merge.directoryRenames=conflict merge A &&
git add b/x &&
mkdir a &&
git mv b/x a/x &&
test_tick &&
git commit -m "D"
)
'
test_expect_success '13e-check: directory rename detection in recursive case' '
(
cd 13e &&
git checkout --quiet D^0 &&
git -c merge.directoryRenames=conflict merge -s recursive C^0 >out 2>err &&
test_i18ngrep ! CONFLICT out &&
test_i18ngrep ! BUG: err &&
test_i18ngrep ! core.dumped err &&
test_must_be_empty err &&
git ls-files >paths &&
! grep a/x paths &&
grep b/x paths
)
'
test_done test_done

View File

@ -7,8 +7,6 @@ test_description='Test automatic use of a pager.'
. "$TEST_DIRECTORY"/lib-terminal.sh . "$TEST_DIRECTORY"/lib-terminal.sh
test_expect_success 'setup' ' test_expect_success 'setup' '
: squelch advice messages during the transition &&
git config --global log.mailmap false &&
sane_unset GIT_PAGER GIT_PAGER_IN_USE && sane_unset GIT_PAGER GIT_PAGER_IN_USE &&
test_unconfig core.pager && test_unconfig core.pager &&

View File

@ -243,10 +243,23 @@ test_expect_success 'no bitmaps created if .keep files present' '
pack=$(ls bare.git/objects/pack/*.pack) && pack=$(ls bare.git/objects/pack/*.pack) &&
test_path_is_file "$pack" && test_path_is_file "$pack" &&
keep=${pack%.pack}.keep && keep=${pack%.pack}.keep &&
test_when_finished "rm -f \"\$keep\"" &&
>"$keep" && >"$keep" &&
git -C bare.git repack -ad && git -C bare.git repack -ad 2>stderr &&
test_must_be_empty stderr &&
find bare.git/objects/pack/ -type f -name "*.bitmap" >actual && find bare.git/objects/pack/ -type f -name "*.bitmap" >actual &&
test_must_be_empty actual test_must_be_empty actual
' '
test_expect_success 'auto-bitmaps do not complain if unavailable' '
test_config -C bare.git pack.packSizeLimit 1M &&
blob=$(test-tool genrandom big $((1024*1024)) |
git -C bare.git hash-object -w --stdin) &&
git -C bare.git update-ref refs/tags/big $blob &&
git -C bare.git repack -ad 2>stderr &&
test_must_be_empty stderr &&
find bare.git/objects/pack -type f -name "*.bitmap" >actual &&
test_must_be_empty actual
'
test_done test_done

View File

@ -1430,6 +1430,13 @@ test_oid () {
eval "printf '%s' \"\${$var}\"" eval "printf '%s' \"\${$var}\""
} }
# Insert a slash into an object ID so it can be used to reference a location
# under ".git/objects". For example, "deadbeef..." becomes "de/adbeef..".
test_oid_to_path () {
local basename=${1#??}
echo "${1%$basename}/$basename"
}
# Choose a port number based on the test script's number and store it in # Choose a port number based on the test script's number and store it in
# the given variable name, unless that variable already contains a number. # the given variable name, unless that variable already contains a number.
test_set_port () { test_set_port () {

View File

@ -1,7 +1,6 @@
#ifndef STATUS_H #ifndef STATUS_H
#define STATUS_H #define STATUS_H
#include <stdio.h>
#include "string-list.h" #include "string-list.h"
#include "color.h" #include "color.h"
#include "pathspec.h" #include "pathspec.h"

View File

@ -42,8 +42,6 @@
*/ */
#include "xinclude.h" #include "xinclude.h"
#include "xtypes.h"
#include "xdiff.h"
#define MAX_PTR UINT_MAX #define MAX_PTR UINT_MAX
#define MAX_CNT UINT_MAX #define MAX_CNT UINT_MAX

View File

@ -20,8 +20,6 @@
* *
*/ */
#include "xinclude.h" #include "xinclude.h"
#include "xtypes.h"
#include "xdiff.h"
/* /*
* The basic idea of patience diff is to find lines that are unique in * The basic idea of patience diff is to find lines that are unique in

View File

@ -20,13 +20,9 @@
* *
*/ */
#include <limits.h>
#include <assert.h>
#include "xinclude.h" #include "xinclude.h"
long xdl_bogosqrt(long n) { long xdl_bogosqrt(long n) {
long i; long i;