Remove the discussion of merge conflicts and replace it with a link to
the guide.
Signed-off-by: Julia Evans <julia@jvns.ca>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Remove some of the detail about how to handle a merge conflict, since
it's explained in detail in the new guide, and there probably isn't
enough detail anyway.
Leave the steps since rebase is special and has a `--skip` option which
the other commands which cause merge conflicts don't have.
Signed-off-by: Julia Evans <julia@jvns.ca>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
All of the info about merge conflicts has been moved to the new guide
Signed-off-by: Julia Evans <julia@jvns.ca>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Introduce a new page, `gitmergeconflicts`, that explains the process of
handling a merge conflict in a way that addresses the following issues,
which came from feedback from Git users on the current explanation of
merge conflicts in the `git merge` man page:
- The process for resolving a merge conflict is only explained in the
`git merge` man page, even though there are several other commands
which can result in conflicts
- Sometimes we use "ours" and "theirs" to refer to the two sides of
the merge conflicts and sometimes we use HEAD and MERGE_HEAD. It should
be consistent. Also the terms "ours" and "theirs" are not explained.
Similarly, it says "The part before the `=======` is typically your
side...", but doesn't explain what "typically" means.
- It introduces the merge format using an analogy to RCS, which very few
Git users have ever used
- In "The only clean-ups you need are to reset the index file to the
`HEAD` commit to reverse 2. and to clean up working tree changes made
by 2. and 3.", it's not clear to users what "2" and "3" are supposed
to mean
- It uses a cultural reference ("Conflict resolution is hard; let's go
shopping.") which is confusing or unfamiliar to some people. I think it
would be clearer for users to use a code example instead.
- It doesn't explain the difference between diff3 and zdiff3
- It sometimes uses the term "area" and sometimes uses the term "hunk"
Also document the unified `--abort`, `--continue` workflow in one
place, since it's a really nice example of a place Git has a consistent
interface between similar commands.
Only discuss merge, rebase, cherry-pick, and revert for now even though
there are other ways that merge conflicts can happen because it's
awkward to talk about `am`, `apply`, and `checkout -m`.
Co-Authored-By: Marie Claire LeBlanc Flanagan <hello@marieflanagan.com>
Helped-by: D. Ben Knoble <ben.knoble+github@gmail.com>
Helped-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Julia Evans <julia@jvns.ca>
Signed-off-by: Marie Claire LeBlanc Flanagan <hello@marieflanagan.com>
Signed-off-by: Julia Evans <julia@jvns.ca>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Doc updates.
* tz/doc-pack-refs-and-refs-fixes:
doc/refs: backtick-quote commands and options consistently
doc/pack-refs: convert synopsis and options to new style
The git-refs doc was converted to the synopsis style in 89be7d2774
(builtin/refs: add '--no-reflog' flag to drop reflogs, 2025-02-21). The
commands and options were not backtick-quoted at that time. 84f3d6e11e
(doc lint: check that synopsis manpages have synopsis inlines,
2025-08-11) applied backtick-quotes to the existing commands and
options.
Subsequently, a number of commands and options were added without such
quoting, leaving the documentation rendered inconsistently. Apply
backtick-quotes to all entries.
Signed-off-by: Todd Zullinger <tmz@pobox.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Replace [verse] with [synopsis] in the SYNOPSIS block and remove
single-quote formatting from the command name.
Backtick-quote all option terms in the OPTIONS section via the included
pack-refs-options.adoc and convert the standalone placeholder _<branch>_
in prose.
Signed-off-by: Todd Zullinger <tmz@pobox.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
The git rev-list command has been augmented with a '--missing-only'
option that filters the output to only show missing objects,
stripping the leading '?' character and suppressing present objects,
which is useful when used in combination with '--missing=print' or
'--missing=print-info'.
* sa/rev-list-missing-only:
rev-list: add --missing-only option to filter output
"git maintenance" triggered "rerere gc" in unappropriate times and
interfered with "git rebase" etc. too much. The conditions "rerere
gc" gets triggered have been tweaked.
* ps/tune-rerere-gc:
builtin/maintenance: improve heuristic for "rerere gc"
rerere: extract logic to determine whether entries are stale
The autostash fallback in 'git checkout -m' has been refined to only
retry when there are local changes. Additionally, a blank line now
visually separates autostash conflict advice from the subsequent
branch-switch message.
* hn/checkout-m-autostash-refine:
checkout: separate autostash conflict advice from branch-switch message
stash: reserve exit status 1 for conflicts
The 'git imap-send' command has been taught to take the '--draft'
option to mark uploaded messages as drafts, which helps some email
clients render them properly for editing and sending.
* wf/imap-send-draft:
imap-send: add --draft to set IMAP \Draft flag
The development helper script to lint gitlink references in the
documentation has been updated to avoid a newer Perl regular
expression syntax that breaks on older Perl versions.
* ta/lint-gitlink-older-perl-fix:
lint-gitlink: don't use empty lower bound in .{0,8}
The documentation for 'git cherry-pick' has been updated to clarify
that the '--no-commit' option intentionally skips setting the
'CHERRY_PICK_HEAD' ref. A test has also been added to ensure this
behavior holds even when the operation stops for conflicts.
* as/cherry-pick-no-commit-doc:
doc: cherry-pick: note --no-commit skips CHERRY_PICK_HEAD
t3507: check no CHERRY_PICK_HEAD after conflicting --no-commit
The gitdatamodel documentation page has been linked from a handful
of key documentaiton pages.
* kh/doc-datamodel:
doc: datamodel: link to the glossary
doc: glossary: link four of the terms to gitdatamodel(7)
doc: git: link to the gitdatamodel(7) tutorial
doc: git: list gitdatamodel(7) as a concept guide
Fix conjoined bullet items for the maintenance strategies in
git-config(1). Reportedly, asciidoctor renders this document correctly
both before and after this patch. asciidoc renders it correctly only
_after_ this patch.
Signed-off-by: Brigham Campbell <me@brighamcampbell.com>
Acked-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
The 'git replay' command has been taught the '--linearize' option to
drop merge commits and linearize the replayed history, mimicking 'git
rebase --no-rebase-merges'.
* tc/replay-linearize:
replay: offer an option to linearize the commit topology
replay: resolve the replay base outside pick_regular_commit()
replay: add helper to put entry into replayed_commits
The regex quantifier {,n} was added in Perl 5.34.0 as a shorthand
for {0,n}. That makes it too new an introduction for Git which
targets Perl 5.26.0.
Even though Documentation/lint-gitlink.perl is a development helper
script, let's stick to the general Perl version requirement for
consistency, and use an explicit zero in .{0,8}.
Signed-off-by: Tuomas Ahola <taahol@utu.fi>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
'git checkout' and 'git worktree add' makes guesses based on a name
of a remote-tracking branch, but does not give an error when such a
remote-tracking branch cannot be uniquely identified, which has
been corrected.
* yn/worktree-ambiguous-remote-advice:
worktree add: treat multiple matches with --guess-remote as an error
worktree add: improve message for ambiguous remote branch name
checkout: improve message for ambiguous remote branch name
checkout: extract function to display advice for ambiguous remotes
The list of what happens when a change is hard to apply states without
qualification that CHERRY_PICK_HEAD is set. Under --no-commit it is
not: d7e5c0cbfb (Introduce CHERRY_PICK_HEAD, 2011-02-19) skips the ref
on purpose there, presuming the user intends to further edit the
result and possibly pick more commits on top.
The option's own description says nothing about the ref or about
authorship. "git commit" reads the author of a cherry-pick from
CHERRY_PICK_HEAD, so without it a plain commit records you as the
author. Say so where the option is described, and say that this is
the point of the option rather than a wrinkle: what is being built is
the user's own work, not a reproduction of the original commit.
Signed-off-by: Aleksei Sviridkin <f@lex.la>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
We linked from the glossary to the data model page in the last commit.
It can also be useful to link the other way for readers who might want
to reference more terminology.
Signed-off-by: Kristoffer Haugsbakk <code@khaugsbakk.name>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Four of the terms in the glossary are discussed in gitdatamodel(7).
Let’s link to the data model page from the glossary.
The phrasing needs to be tweaked based on what gitdatamodel(7) offers
for each term compared to the glossary, or even other pages (see the
git-reflog(1) mention). For instance, the ref/reference discussion can
be called a “see also” since the glossary here already goes into
detail. On the other hand, gitdatamodel(7) offers more details on
the subject of “the index”.
Let’s also add gitdatamodel(7) to See Also. It is at least as relevant
as the other tutorial pages that are already mentioned.
Signed-off-by: Kristoffer Haugsbakk <code@khaugsbakk.name>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
The previous commit added the first mention of gitdatamodel(7) here,
under Guides. But there are also other sections where a mention is
relevant.
Let’s mention it:
• under Description, since it is as useful as the other tutorials
already mentioned there for those who are interested;
• under Terminology, since it complements gitglossary(7) as a
pedagogical rather than reference source for the core terms;[1] and
• under See Also, since the other tutorials (plus the user manual) are
mentioned there.
We don’t need to mention it under Further Documentation since we now
mention it under Description.
† 1: See dee80940 (doc: add an explanation of Git's data model,
2025-11-12):
`gitglossary`. This makes a good effort, but it's an
alphabetically ordered dictionary and a dictionary is not a
good way to learn concepts. You have to jump around too much
and it's not possible to present the concepts in the order
that they should be explained.
Signed-off-by: Kristoffer Haugsbakk <code@khaugsbakk.name>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
The "rerere-gc" maintenance task is responsible for pruning rerere
entries older than a certain configurable cutoff point. Whether or not
the task gets run during auto-maintenance can be configured via
"maintenance.rerere-gc.auto":
- A negative value indicates that maintenance should always run.
- A zero value indicates that maintenance should never run.
- Otherwise, a positive value indicates that maintenance should always
run in case we have at least a single rerere entry.
While the first two conditions are sensible, the last one is less so as
it does not account for whether we would even prune old entries in the
first place. Instead, it effectively implies that we unconditionally
spawn "git rerere gc" when rerere is enabled. Chances are high though
that there is nothing to prune, as the default cutoff dates are 60 days
for resolved rerere entries and 15 days for unresolved ones.
Besides being a waste of compute, it also obstructs concurrent processes
that want to write new resolutions as garbage collection takes a central
lock file, as reported in [1]. That race is a longstanding one that
existed even before we introduced fine-grained maintenance tasks, and
the proper fix is to use a locking timeout in the writing processes. But
the race is made worse by us performing garbage collection a lot more
often.
Refine the heuristic to take into account whether any entries can be
pruned in the first place. This ensures that we'll only ever run this
task in situations where it will do anything, and should thus result in
a lot less frequent invocations of "git rerere gc".
Furthermore, tweak the meaning of "maintenance.rerere-gc.auto" so that
positive values allow the user to configure the number of prunable
entries that need to exist before we run it and set the default value to
512. This number is pulled out of thin air, but it ensures that we know
to batch-delete entries instead of pruning every single entry that is
older than the cutoff point.
Note that this now requires us to actually open the rerere-entry
directories and stat the individual files in there, which does add a bit
of overhead when one has lots of rerere entries. To counteract this
overhead, we thus use the same sampling heuristic as we do for loose
objects, where we only consider those entries that start with a "17".
[1]: <pull.2214.git.1788337897490.gitgitgadget@gmail.com>
Reported-by: Thomas Bachem <mail@thomasbachem.com>
Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
When working with partial clones, callers often need only the missing
object IDs. Today that means post-processing --missing=print to drop
present objects and strip the leading '?':
git rev-list --objects --all --missing=print | perl -ne 'print if s/^[?]//'
This is for a one-shot walk, not a fetch loop. Callers already have
--missing=print and strip the leading '?'. Gitaly does that when packing
a quarantine: '?' lines are objects that must already exist in the main
repo. Tests do the same (is this blob still missing). --missing-only is
just that list without the prefix.
Add --missing-only. Use it with --missing=print or --missing=print-info
to print only missing objects. --missing= still picks the format;
--missing-only only filters. The leading '?' is omitted. With
print-info, path= and type= are still shown.
Require --missing=print or --missing=print-info. Reject --count and
--disk-usage.
Signed-off-by: Siddharth Asthana <siddharthasthana31@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
"git stash apply", "pop" and "branch" exit with status 1 both when
applying the stash entry resulted in conflicts and when they fail for
other reasons, so callers cannot tell the two apart.
Follow the convention of "git merge-tree" and the merge strategies,
which exit with status 1 to indicate conflicts and with a different
non-zero status for errors: those subcommands now exit with status 1
only when applying the stash entry resulted in conflicts, in which
case the stash entry is left in place, and exit with status 128, the
status die() uses, when they fail for other reasons. Document the
exit statuses.
The only subcommand implementations that can return a positive value
are "apply", "pop" and "branch", which return the value of
do_apply_stash(): "apply" returns it directly, and "pop" and "branch"
drop the stash entry, via do_drop_stash(), which always returns 0,
only when the application succeeded. do_apply_stash() only returns a
positive value when the three-way merge was unclean. cmd_stash() now
maps negative values to 128 and passes positive values through as the
exit status, so exit status 1 unambiguously indicates conflicts.
enum stash_apply_result makes the convention explicit, and the
autostash helpers use it to tell users that their stashed changes
were saved when applying them fails.
Signed-off-by: Harald Nordgren <haraldnordgren@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
The global variable 'fetch_if_missing' has been moved to a member in
'struct repository', continuing the libification process and
allowing per-repository control (such as for submodules).
* ty/repository-fetch-if-missing:
repository: move fetch_if_missing into struct repository
The documented purpose of imap-send is to upload draft emails for sending
later, but it did not have any way to mark the messages as \Draft, so some
email clients presented the result as an un-editable, un-sendable email
even if it happened to be in a "Drafts" folder.
Signed-off-by: Wolfgang Faust <contrib-git@wolfgangfaust.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
One of the stated goals of git-replay(1) is to allow implementing the
git-rebase(1) functionality on the server side.
The default mode of git-rebase(1) is to act as if `--no-rebase-merges`
was given. This mode drops merge commits instead of replaying them, and
linearizes the history into a sequence of regular (single-parent)
commits.
Add option `--linearize` to git-replay(1) to do the same. Each replayed
commit is stacked on top of the previously replayed one. When a merge is
encountered, the commits reachable from all of its sides are replayed
into the single line and the merge itself is dropped.
If a ref was pointing to a merge commit, that ref is updated to the
merge's last replayed ancestor.
git-replay(1) accepts multiple branches, for example:
$ git replay --onto main topic1 topic2
Without `--linearize` this replays 'topic1' and 'topic2' onto 'main'
(keeping shared portions of history shared and divergent parts
divergent) and updates both refs.
Due to current implementation limitations, replaying multiple branches
with `--linearize` is disallowed to avoid concatenating unrelated
histories into a single line. For the same reason disallow the use of
`--contained` with `--linearize`.
Users who want to linearize multiple branches are advised to do this in
separate git-replay(1) invocations. Linearizing multiple branches at
once might be added later.
Note that `--linearize` is not modeled after git-rebase(1)'s
`--rebase-merges[=<mode>]` interface. Recreating merges, by preserving
their topology, is a distinct operation that would be a separate mode.
`--linearize` only drops merges and replays commits linearly. So
git-replay(1) uses its own option rather than reusing that interface.
Based-on-patches-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Toon Claes <toon@iotcl.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
The threshold for geometric repacking to trigger based on loose
object count has been adjusted to match that of 'git gc --auto',
preventing over-aggressive repacking during concurrent writes.
* ps/odb-geometric-repack-loose-threshold:
odb/files: be less aggressive with geometric repacking
The trailer parsing machinery has been updated to avoid mistaking
lines that begin with a URL (e.g., 'https://...') as trailer lines.
This prevents intended textual URLs from being mangled or mistakenly
treated as metadata keys.
* kh/trailers-no-urls:
trailers: stop recognizing URLs as trailers
The documentation for 'git format-rev' has been updated to use the
[synopsis] block definition on code blocks to properly highlight
placeholders, and a quoting inconsistency in the running text has
been fixed.
* kh/format-rev-doc-synopsis:
doc: format-rev: use [synopsis] on code block
doc: format-rev: quote subject placeholder before and after
When 'git worktree add <path>' is invoked without <commit-ish> and
with the --guess-remote option (or when worktree.guessRemote is set to
true), it tries to find a remote-tracking branch matching the basename
of <path>.
Currently, the behavior when multiple matches are found is the same as
when no match is found: it falls back to creating a branch from
HEAD. This has been the behavior since 71d6682d8c (worktree: add
--guess-remote option to add subcommand, 2017-11-29), when the option
was first introduced.
However, if the specified <path> matches any remote-tracking branch,
we infer that the user intended to use one of the remote-tracking
branches as the start-point rather than HEAD. So we abort the creation
of the branch and worktree when there are multiple matches, and
instruct the user to choose the start-point.
Signed-off-by: Yoichi NAKAYAMA <yoichi.nakayama@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
'git repack' has been taught '--drop-filtered' to delete local
promisor blobs exceeding a limit (currently 'blob:limit=') in partial
clones, reclaiming space. Guards prevent running during other
operations or if referenced by the index.
* ss/repack-drop-filtered:
builtin/repack: add guards for --drop-filtered
builtin/repack: actually drop filtered promisor blobs
builtin/repack: enumerate promisor blobs for --drop-filtered
repack-promisor: allow excluding objects from the rebuilt promisor pack
list-objects-filter: add list_objects_filter__filter_oidset()
builtin/repack: add --drop-filtered and --dry-run options