Commit Graph

400 Commits (34f761734b49bb9372462a430f7f9e8b49b1bc2e)
 

Author SHA1 Message Date
Elijah Newren 34f761734b INSTALL.md: simplify manual installation instructions
Make use of `git --man-path` and `git --html-path` to simplify the
manual installation instructions a bit.  Also, there appears to be a
site.getsitepackages() call in python to give similar information about
where git_filter_repo.py can be installed.

Signed-off-by: Elijah Newren <newren@gmail.com>
4 years ago
Elijah Newren a238e3b7e6 git-filter-repo.txt: discourage use of random clone flags
Flags like --local, --shared, --reference (and --dissociate), and
--origin would all mess up the fresh clone checker.  Attempting to
defend against all of them would not only be costly, but make it harder
to draw the line about guesses as to whether a repository is a fresh
clone or not.  --origin also has problems in that filter-repo has
special handling for the 'origin' remote that I don't want to apply to
other random remotes.

Flags like --depth, --single-branch, and --no-tags could prevent enough
data from being downloaded to do a full rewrite and result in a
partially rewritten or possibly even corrupt history (no idea how
shallow clones interact; probably badly).  --filter would also make the
repo start without enough info though it'd at least be downloaded on
demand; it'd still be a really slow way to do it, though, so it's a bad
idea.

filter-repo doesn't really provide an easy mechanism to rewrite a repo
and its submodule simultaneously, so recursing submodules seems useless
and unhelpful.  --shallow-submodules would be bad for at least the same
reasons --depth is for the parent module, assuming we handled
submodules.  --remote-submodules just provides a way to make the repo
dirty to start, which is counter-productive.  --jobs could be useful, if
recursing submodules was.

--no-checkout might be safe to use and --sparse might also be okay for
as long as it only affects the working tree, but in both cases why not
go --bare or --mirror if you're doing that?  Likewise, --no-hardlinks is
useless given that we're already saying people need to use --no-local.

-b would be okay to use, but why wouldn't you just change the default
branch on the server rather than just within this one clone used for
rewriting the history?  Whether you push back to the original repository
or to a new repo, you'd have to take a separate step to change it in
that remote repo.  And if you really will use this new local repository
as the official source, then you can switch branches at the end of the
rewrite just as easily.

--separate-git-dir and --template might be okay to use, I haven't
tested.  If either doesn't work now, or breaks at any point in the
future, I feel much better being able to say, "I told you to only use
these three flags to git clone."

-u only affects the ability to receive the clone; it's fine to use.
Also, -q only affects the console output during the clone operation, so
you could use it.

There will probably be more flags added to git-clone over time.  Testing
against all of them is insanity.  Recommend people only use --no-local,
--bare, and --mirror, with the first only needed when cloning from a
local filesystem, and the other two never needed but allowed for those
that prefer.

Signed-off-by: Elijah Newren <newren@gmail.com>
4 years ago
Elijah Newren 49d6f02ff8 filter-repo: clarify interactions between path filtering and path renaming
Signed-off-by: Elijah Newren <newren@gmail.com>
4 years ago
Elijah Newren 3e1bff264c Revert "filter-repo: fix ugly bug with mixing path filtering and renaming"
This reverts commit df6c8652a2.  The
motivating example was wrong; path renaming should not be involved in
path filtering, it only says how paths should be renamed if they happen
to be selected.  A subsequent commit will improve the documentation.

Signed-off-by: Elijah Newren <newren@gmail.com>
4 years ago
Elijah Newren a4c12253a8 git-filter-repo.txt: briefly explain steps for pushing to original url
Signed-off-by: Elijah Newren <newren@gmail.com>
4 years ago
Elijah Newren b8ebda97dd contrib: avoid applying --replace-text to binary files in bfg-ish
Signed-off-by: Elijah Newren <newren@gmail.com>
4 years ago
Elijah Newren 86569ee7ac Contributing.md: add a small clarification about line coverage
Signed-off-by: Elijah Newren <newren@gmail.com>
4 years ago
Elijah Newren 23bec32283 contrib, docs: make discovery of code formatting and linting easier
The desire to format or lint code throughout history has arisen several
times.  It's more natural to do this in filter-branch since it somewhat
forces people to run external commands, but we have an example contrib
demo that shows how to run an external command on each file in history
that I created even before any of these requests came in and yet I still
periodically get requests about it.

Make lint-history ever-so-slightly easier to apply to a subset of
filenames, and include its usage as an extra cheat sheet comparison for
filter-branch-vs-filter-repo commands.

Signed-off-by: Elijah Newren <newren@gmail.com>
4 years ago
Elijah Newren bd2c9c4d4d contrib: new simple no-op-example
The purpose of this example is to solely show what to import and run to
recover filter-repo's behavior as-is.  It doesn't modify any behavior,
but instead exists as an example so people can easily find a good
starting point for making their own modifications.

Signed-off-by: Elijah Newren <newren@gmail.com>
4 years ago
Elijah Newren caa05d15b4 filter-repo: make default replacement text a variable
Allow external scripts that import git-filter-repo to change the value
of the default replacement text instead of having it hardcoded within
some function.

Signed-off-by: Elijah Newren <newren@gmail.com>
4 years ago
Elijah Newren 31f00a9ff8 filter-repo: avoid applying --replace-text to binary files
--replace-text is meant to replace _text_ throughout the repository, not
binary data.  Use the same scheme as the lint-history script uses to
avoid applying the changes to binary blob data.

Reported-by: Tobias Gruetzmacher <tobias-git@23.gs>
Signed-off-by: Elijah Newren <newren@gmail.com>
4 years ago
Elijah Newren 859e66ae1c converting-from-filter-branch.md: add a small clarification
Signed-off-by: Elijah Newren <newren@gmail.com>
4 years ago
Elijah Newren d32f6258a8 converting-from-bfg-repo-cleaner.md: add a small clarification
Signed-off-by: Elijah Newren <newren@gmail.com>
4 years ago
Elijah Newren d87b665ed4 git-filter-repo.txt: connect --no-local and fresh clones more thoroughly
Signed-off-by: Elijah Newren <newren@gmail.com>
4 years ago
Elijah Newren 469a3e10f2 filter-repo (README): separate sections for different tools
Our showing of how to handle the simple example with different tools
combined three different tools into a single section which I think made
it slightly harder to read and follow.  It also concentrated almost
exclusively on filter-branch.  Provide a separate section for each tool,
and provide more details for BFG and fast-export/fast-import.

Signed-off-by: Elijah Newren <newren@gmail.com>
4 years ago
Elijah Newren 8ba3566119 filter-repo (README): link cheat sheets from usage section too
Signed-off-by: Elijah Newren <newren@gmail.com>
4 years ago
Elijah Newren cdb7b77f07 filter-repo: repack with --source or --target
When using --source or --target in combination with filtering paths,
users were surprised out how large the resulting repository was.  The
usage of --source and --target were turning off repacking; while we
don't want repacking for partial history rewrites and --source and
--target turn on some of the other features we want with partial history
rewrites, repacking is something that we still want turned on.

Reported-by: Alexey Volkov <alexey.volkov@ark-kun.com>
Signed-off-by: Elijah Newren <newren@gmail.com>
4 years ago
Elijah Newren 2bfb9cf261 git-filter-repo.txt: fix extraneous space
Signed-off-by: Elijah Newren <newren@gmail.com>
4 years ago
Elijah Newren 7b18e6d7f5 filter-repo: fix --prune-degenerate=never with path filtering
When combining `--prune-degenerate never` with a `--path` specification,
we could end up trying to write a parent out to the fast-import stream
whose value was actually None.  The problem occurs when the parents of
a merge commit are filtered out by the path specification, leaving us
only with no-longer-extant parents.  In such a case, we need to filter
out these 'None' (i.e. invalid) parents.  The point of
`--prune-degenerate never` is to avoid removing parents that are either
the same as or an ancestor of another parent, not to avoid removing
non-existent parents.  Remove the non-existent parent(s).

Reported-by: Gaurav Kanoongo (@gauravkanoongo on GitHub)
Signed-off-by: Elijah Newren <newren@gmail.com>
4 years ago
Elijah Newren df6c8652a2 filter-repo: fix ugly bug with mixing path filtering and renaming
There's also a fix in here to make sure to throw an error if users are
trying to rename paths and use --invert-paths; it's not clear at all
what that would even mean.  But that also becomes important later...

Due to the ability to either filter wanted paths (default), or to just
specify unwanted paths (with --invert-paths), I keep a special
args.inclusive variable to track whether a "match" means we want the
path or not.  There are some special cases, notably when there are no
filters present (meaning e.g. no --path specifications, at most there
are some --path-rename values provided).  When there are no filters
present, that means we should keep paths even if we don't "find a match"
against any of the filters.

Now, since the rename code was embedded in the same loop as the filter
checks, it unfortunately was also being checked against the
args.inclusive setting despite never setting whether it found a match.
That happened to work in the special case that there were no filtering
paths but only because of the special logic for that case.  Since
renaming only makes sense if --invert-paths is not specified, any path
we rename is one we always want to keep.  Make sure we do.

Reported-by: Nadège (@nagreme on GitHub)
Signed-off-by: Elijah Newren <newren@gmail.com>
4 years ago
Elijah Newren 0375758806 filter-repo: fix possible deadlock in sanity_check_args
I'm a little surprised that stdout buffers must have filled up on MacOS X, but
either way we don't have to wait for the '-h' processes to finish before
attempting to read stdout.  In fact, since we weren't storing the returncode
attribute from calling p.wait(), there wasn't much point in doing so.  Trying
to read all stdout all at once is going to implicitly take until the process
finishes anyway, so just do that.

Reported-by: Benoit Lefèvre <contact@benoit-lefevre.org>
Signed-off-by: Elijah Newren <newren@gmail.com>
4 years ago
Elijah Newren 15494bba8a filter-repo: make git version requirement error message more direct
Users won't know which versions of git have --mark-tags, --reencode, or
--combined-all-paths options for fast-export and diff-tree.  I didn't
either when I wrote those messages because it wasn't in a released
version of git.  Now that they are in released versions and have been
for a while, we can simplify the messages to just state which git
version is needed.

Signed-off-by: Elijah Newren <newren@gmail.com>
4 years ago
Elijah Newren 1e2d0e91cb Documentation: add more detailed explanation of safety checks and --force
I occasionally get people doing special things, or see people
recommending to others to just use --force.  Add some explanations
behind the safety checks so that those doing special things know when
it's okay, and to explain why it's a really bad idea to casually or
haphazardly recommend others use --force.

Signed-off-by: Elijah Newren <newren@gmail.com>
4 years ago
Elijah Newren 3dfaf3874e filter-repo: fix --no-local error when there is no remote
Commit 011c646ee8 (filter-repo: suggest --no-local when cloning local
repos, 2020-05-15) added an additional message to the error to make it
more clear what to do when cloning local repos.  However, if there was
no remote, then the code path would run os.path.isdir(None), triggering
a traceback.  Fix the logic.

Signed-off-by: Elijah Newren <newren@gmail.com>
4 years ago
Elijah Newren 423b7d2c89 INSTALL: streamline a bit and guide folks to package managers
Now that several package managers are packaging filter-repo (Debian and
Ubuntu seem to be the primary holdouts, but maybe treating Linux as
"covered" will pressure them to package it too), guide people to use
package managers for easy installation and streamline the wording.
Still keep the old instructions around, just move them later.

Signed-off-by: Elijah Newren <newren@gmail.com>
4 years ago
Elijah Newren 7e1184cd42 git-filter-repo.txt: add more --paths-from-file examples with large filtering lists
Signed-off-by: Elijah Newren <newren@gmail.com>
4 years ago
Elijah Newren 5c4637ff81 Documentation: add guides for people converting from filter-branch or BFG
Signed-off-by: Elijah Newren <newren@gmail.com>
4 years ago
Elijah Newren 4cfc765eb1 filter-repo: allow removing .git directories from history
Commit 7cfef09e9b (filter-repo: warn users who try to use invalid path
components, 2019-12-26) attempt to protect against using invalid path
components, but also added a check against a path that has sometimes
been valid in the past and which users might want to be able to remove
from their history.  Relax the check so that users can remove '.git'
directories in subdirectories (or even at the toplevel) from their
history.

Signed-off-by: Elijah Newren <newren@gmail.com>
4 years ago
Elijah Newren db9ac1fffe git-filter-repo.txt: add documentation of --no-ff option
Commit 5e04dff097 (filter-repo: add new --no-ff option, 2020-01-01)
added support for a --no-ff option, but only added documentation in the
built-in output, not in the intended-to-be-more-complete manual.  Add
documentation to the manual for this option.

Signed-off-by: Elijah Newren <newren@gmail.com>
4 years ago
Elijah Newren 2833ef275f filter-repo: throw an error if user specifies any path starting with a slash
All paths are intended to be relative paths, relative to the project
root, not to the filesystem root.  There have been a few people who
didn't understand this, and then ended up with fast-import crashes that
are not very clear.  Check for it early and throw a simple error message
instead.

Signed-off-by: Elijah Newren <newren@gmail.com>
4 years ago
Elijah Newren 764e0e00dd git-filter-repo.txt: add examples for --[to-]subdirectory-filter
I had lots of examples of these being horribly mis-used and being used in place
of each other; add some examples with some description of the repository layout
to try to avoid all that confusion.

Signed-off-by: Elijah Newren <newren@gmail.com>
4 years ago
Elijah Newren e834379254 filter-repo: clarify usage of --use-base-name
fast-export/fast-import only work with filenames (using full path from
the root of the repository); thus that's all that filter-repo works
with.  Full pathnames implicitly include all leading directories as part
of the pathname, which is what allows us to match against directories.
However, it obviously means --use-base-name can't be used to match paths
against directories.

Signed-off-by: Elijah Newren <newren@gmail.com>
4 years ago
Elijah Newren 7c877cd750 filter-repo: make --version more robust against modified shebangs
Signed-off-by: Elijah Newren <newren@gmail.com>
4 years ago
Elijah Newren e9c2d9adb5 filter-repo: ensure we write final newline after final progress update
We try to write 'Parsed %d commits' messages only after enough time has
past to avoid writing to stdout becoming a bottleneck.  However, there
was a slight logic error that would cause it to only print the final
newline if there was a new message since the last progress update,
leaving a small race condition where we might miss it.

Reported-by: Valentyn Shtronda (@valiko-ua)
Signed-off-by: Elijah Newren <newren@gmail.com>
4 years ago
Elijah Newren 011c646ee8 filter-repo: suggest --no-local when cloning local repos
Cloning local repos by default makes a bunch of hardlinks, giving you a
non-packed repository, and leading folks to use and suggest --force.
That, of course, bypasses the important fresh clone checks to prevent
people from accidentally and irrecoverably deleting their non-backed-up
data.  Let's make it easier for people to avoid (and suggest) that
mistake.

Signed-off-by: Elijah Newren <newren@gmail.com>
4 years ago
Elijah Newren c0c37a7656 filter-repo: fix bitrotted documentation links
Signed-off-by: Elijah Newren <newren@gmail.com>
4 years ago
Elijah Newren 427b265195 Merge branch 'mr/filter-lamely-and-special-filenames' into master
Signed-off-by: Elijah Newren <newren@gmail.com>
4 years ago
Marius Renner 3427ee171b contrib: fix special character handling in filter-lamely
filter-lamely does not handle filenames with special characters (such as
äöü or even \n and \t) properly when using a tree filter or index
filter. It either does not quote the input to git correctly or parses
git output incorrectly, causing affected filenames to be mangled with
extraneous double quotes in the history or even crashing the program.

Make filter-lamely correctly handle such filenames by using
NUL-delimited input and output modes for the affected git commands.

Signed-off-by: Marius Renner <marius@mariusrenner.de>
4 years ago
Elijah Newren f164f2b2e6 Merge branch 'kf/fix-example-typo' into master
Signed-off-by: Elijah Newren <newren@gmail.com>
4 years ago
Kate F 420aa32dac git-filter-repo.txt: Fix typo for example
Signed-off-by: Kate F <kate@elide.org>
4 years ago
Elijah Newren 3a394ca152 Makefile: a few sanity checks for releasing
Signed-off-by: Elijah Newren <newren@gmail.com>
4 years ago
Elijah Newren 9928b7cb3e t9390: add missing '&&' in command chain
Signed-off-by: Elijah Newren <newren@gmail.com>
4 years ago
Elijah Newren e11343e504 filter-repo: handle typechange modifications when first parent is pruned
Commit 509a624b (filter-repo: fix issue with pruning of empty commits,
2019-10-03) added code to get a new list of file changes when the first
parent was pruned.  However, this logic did not handle cases where one
of the file modifications was a typechange.  Add the necessary logic to
handle that case.

Signed-off-by: Elijah Newren <newren@gmail.com>
4 years ago
Elijah Newren 4f84a74ada filter-repo: use more expensive prunability checks when needed
When users are inserting new objects into the stream, we cannot make as
many assumptions and need to do more careful checks for whether commits
become empty or not.

Signed-off-by: Elijah Newren <newren@gmail.com>
4 years ago
Elijah Newren b1fae4819a filter-repo: relax the definition of freshly packed
transfer.unpackLimit defaults to 100, meaning that if less than 100
objects exist in the repository, git will automatically unpack the
objects to be loose as part of the clone operation.  So, if there are no
packs and less than 100 objects, consider the repo to be freshly packed
for purposes of our fresh clone sanity checks.

Signed-off-by: Elijah Newren <newren@gmail.com>
4 years ago
Elijah Newren fe33fc42b3 filter-repo: avoid dying with --analyze on commits with unseen parents
analyze_commit() calls add_commit_and_parents() which does a sanity
check that we have seen all parents previously.  --refs breaks that
assumption, so we need to workaround that check when ref limiting is in
effect.

Signed-off-by: Elijah Newren <newren@gmail.com>
4 years ago
Elijah Newren 46549e7d3f lint-history: point people to issue with more linting examples
Signed-off-by: Elijah Newren <newren@gmail.com>
4 years ago
Elijah Newren 4c28ed6b8a Merge branch 'sb/setup-idempotency' into master
Signed-off-by: Elijah Newren <newren@gmail.com>
4 years ago
Sirio Balmelli 9cf87ae036
setup.py: test for FileExistsError on symlink
Multiple runs of setuptools encounter a FileExistsError exception
trying to re-symlink the same files.

This exception is safe to ignore: the files were already symlinked
so the call can be considered successful.

Signed-off-by: Sirio Balmelli <sirio@b-ad.ch>
4 years ago
Elijah Newren b9c62540b7 filter-repo: fix cache of file renames
Users may have long lists of --path, --path-rename, --path-regex, etc.
flags (or even a --paths-from-file option with a lot of entries in the
file).  In such cases, we may have to compare any given path against a
lot of different values.  In order to avoid having to repeat that long
list of comparisons every time a given path is updated, we long ago
added a cache of the renames so that we can compute the new name for a
path once and then just reuse it each time a new commit updates the old
filepath.

Sadly, I flubbed the implementation and instead of setting
   cache[oldname] = newname
I somehow did the boneheaded
   cache[newname] = newname
For most repositories and rewrites, this would just have the effect of
making the cache useless, but it could wreak various kinds of havoc if
a newname matched the oldname of some other file.

Make sure we record the mapping from OLDNAME to newname to fix these
issues.

Signed-off-by: Elijah Newren <newren@gmail.com>
4 years ago