|
|
(6 intermediate revisions by the same user not shown) |
Line 1: |
Line 1: |
| = Git Magic = | | = Git Magic = |
|
| |
|
| == Safety Precautions ==
| | [[Sysadmin/GitKdeOrgManual#Advanced_Git]] |
| | |
| Always work on a disposable copy of the repo with all the remotes removed, so if you screw up, it doesn't really matter. Also, work on a separate branch. That way, you can use <tt>git reset --hard <original-branch></tt> to get back to the starting state.
| |
| | |
| == Merging in complete history ==
| |
| | |
| Used this for moving files from kapidox to kdoctools. Good when the history of the source repo doesn't contain too much you won't care about in the target repo. Preserves commit identities.
| |
| | |
| Create a commit in the source repo that removes any files you don't want to copy, and rearranges the remaining files to be as you want them to appear in the target repo. Then, in the target repo, do:
| |
| | |
| git fetch <path to source repo>
| |
| GIT_INDEX_FILE=.git/tmp-index git read-tree FETCH_HEAD
| |
| GIT_INDEX_FILE=.git/tmp-index git checkout-index -a -u
| |
| git update-index --add -- $(GIT_INDEX_FILE=.git/tmp-index git ls-files)
| |
| cp .git/FETCH_HEAD .git/MERGE_HEAD
| |
| sed -i 's/^\([a-z0-9]*\)\s.*/\1/' .git/MERGE_HEAD
| |
| git commit
| |
| | |
| == Filtering ==
| |
| | |
| If you want to trim the history first (which will change the commit identities), you can do something like
| |
| | |
| git filter-branch --prune-empty --tree-filter "find -type f -\! -path './.git/*' -\! -name foo.\* -delete" HEAD
| |
| | |
| This example will remove everything that does not match <tt>foo.*</tt>. Note the <tt>-path</tt> argument to <tt>find</tt> that makes sure you don't delete any of git's own files. <tt>--prune-empty</tt> will remove non-merge commits that no longer have any effect on the tree.
| |
| | |
| More complex filters are possible; doing as much as possible in the same filter-branch command is probably a good thing to aim for, especially if you want to record the original commit SHA (using <tt>--msg-filter</tt>). When I wanted to just grab the commits relevant to the two <tt>FindDocBook*.cmake</tt> files in extra-cmake-modules (which had faked history from kdelibs), I did
| |
| | |
| git filter-branch \
| |
| --tree-filter "find -type f -\! -path './.git/*' -\! -name FindDocBook\*.cmake -delete" \
| |
| --msg-filter 'sed -e "/^CCMAIL/d" -e "/^REVIEW/d"; echo; echo "Commit $GIT_COMMIT in extra-cmake-modules"' \
| |
| --prune-empty \
| |
| HEAD
| |
| | |
| followed by
| |
| | |
| git filter-branch --parent-filter "sed -e 's/-p 755debcea57d6ddab0cf851117fb00f3ab39af6f//' -e 's/-p 91d8128e5fc3f20a4621e2f2516ddd34b979bf01//'" -f HEAD
| |
| | |
| where the two commit SHAs were cut-off points: I didn't want those commits or anything preceding them (because they didn't contain the file I was interested in). These were SHAs ''after'' the first filter-branch; the reason I couldn't put them in the first filter-branch appears to be because by the time a commit was reached, its parents had already been rewritten, and so their SHAs had changed.
| |