Mercurial > public > mercurial-scm > hg-stable
view hgmerge @ 4531:b51a8138292a
Avoid extra filelogs entries.
Right now, there are some situations in which localrepo.filecommit can
create filelog entries even though they're not needed. For example:
- permissions for a file have changed;
- qrefresh can create a filelog entry identical to its parent (see the
added test);
- convert-repo creates extra filelog entries in every merge where the
first parent has added files (for example, changeset ebebe9577a1a of
the kernel repo added extra filelog entries to files in the
arch/blackfin directory, even though the merge should only touch the
drivers/ata directory). This makes "hg log file" in a converted repo
less useful than it could be, since it may mention many merges that
don't actually touch that specific file.
They all come from the same basic problem: localrepo.commit (through
filecommit) creates new filelog entries for all files passed to it
(except for some cases during a merge).
Patch and test case provided by Benoit.
This should fix issue351.
author | Alexis S. L. Carvalho <alexis@cecm.usp.br> |
---|---|
date | Sat, 09 Jun 2007 01:04:28 -0300 |
parents | 6a03cff2b0f5 |
children | e4480f2b61e9 |
line wrap: on
line source
#!/bin/sh # # hgmerge - default merge helper for Mercurial # # This tries to find a way to do three-way merge on the current system. # The result ought to end up in $1. Script is run in root directory of # repository. # # Environment variables set by Mercurial: # HG_FILE name of file within repo # HG_MY_NODE revision being merged # HG_OTHER_NODE revision being merged set -e # bail out quickly on failure LOCAL="$1" BASE="$2" OTHER="$3" if [ -z "$EDITOR" ]; then EDITOR="vi" fi # find decent versions of our utilities, insisting on the GNU versions where we # need to MERGE="merge" DIFF3="gdiff3" DIFF="gdiff" PATCH="gpatch" type "$MERGE" >/dev/null 2>&1 || MERGE= type "$DIFF3" >/dev/null 2>&1 || DIFF3="diff3" $DIFF3 --version >/dev/null 2>&1 || DIFF3= type "$DIFF" >/dev/null 2>&1 || DIFF="diff" type "$DIFF" >/dev/null 2>&1 || DIFF= type "$PATCH" >/dev/null 2>&1 || PATCH="patch" type "$PATCH" >/dev/null 2>&1 || PATCH= # find optional visual utilities FILEMERGE="/Developer/Applications/Utilities/FileMerge.app/Contents/MacOS/FileMerge" KDIFF3="kdiff3" TKDIFF="tkdiff" MELD="meld" type "$FILEMERGE" >/dev/null 2>&1 || FILEMERGE= type "$KDIFF3" >/dev/null 2>&1 || KDIFF3= type "$TKDIFF" >/dev/null 2>&1 || TKDIFF= type "$MELD" >/dev/null 2>&1 || MELD= # Hack for Solaris TEST="/usr/bin/test" type "$TEST" >/dev/null 2>&1 || TEST="/bin/test" type "$TEST" >/dev/null 2>&1 || TEST="test" # random part of names RAND="$RANDOM$RANDOM" # temporary directory for diff+patch merge HGTMP="${TMPDIR-/tmp}/hgmerge.$RAND" # backup file BACKUP="$LOCAL.orig.$RAND" # file used to test for file change CHGTEST="$LOCAL.chg.$RAND" # put all your required cleanup here cleanup() { rm -f "$BACKUP" "$CHGTEST" rm -rf "$HGTMP" } # functions concerning program exit success() { cleanup exit 0 } failure() { echo "merge failed" 1>&2 mv "$BACKUP" "$LOCAL" cleanup exit 1 } # Ask if the merge was successful ask_if_merged() { while true; do echo "$LOCAL seems unchanged." echo "Was the merge successful? [y/n]" read answer case "$answer" in y*|Y*) success;; n*|N*) failure;; esac done } # Clean up when interrupted trap "failure" 1 2 3 6 15 # HUP INT QUIT ABRT TERM # Back up our file (and try hard to keep the mtime unchanged) mv "$LOCAL" "$BACKUP" cp "$BACKUP" "$LOCAL" # Attempt to do a non-interactive merge if [ -n "$MERGE" -o -n "$DIFF3" ]; then if [ -n "$MERGE" ]; then $MERGE "$LOCAL" "$BASE" "$OTHER" 2> /dev/null && success elif [ -n "$DIFF3" ]; then $DIFF3 -m "$BACKUP" "$BASE" "$OTHER" > "$LOCAL" && success fi if [ $? -gt 1 ]; then echo "automatic merge failed! Exiting." 1>&2 failure fi fi # on MacOS X try FileMerge.app, shipped with Apple's developer tools if [ -n "$FILEMERGE" ]; then cp "$BACKUP" "$LOCAL" cp "$BACKUP" "$CHGTEST" # filemerge prefers the right by default $FILEMERGE -left "$OTHER" -right "$LOCAL" -ancestor "$BASE" -merge "$LOCAL" [ $? -ne 0 ] && echo "FileMerge failed to launch" && failure $TEST "$LOCAL" -nt "$CHGTEST" && success || ask_if_merged fi if [ -n "$DISPLAY" ]; then # try using kdiff3, which is fairly nice if [ -n "$KDIFF3" ]; then $KDIFF3 --auto "$BASE" "$BACKUP" "$OTHER" -o "$LOCAL" || failure success fi # try using tkdiff, which is a bit less sophisticated if [ -n "$TKDIFF" ]; then $TKDIFF "$BACKUP" "$OTHER" -a "$BASE" -o "$LOCAL" || failure success fi if [ -n "$MELD" ]; then cp "$BACKUP" "$CHGTEST" # protect our feet - meld allows us to save to the left file cp "$BACKUP" "$LOCAL.tmp.$RAND" # Meld doesn't have automatic merging, so to reduce intervention # use the file with conflicts $MELD "$LOCAL.tmp.$RAND" "$LOCAL" "$OTHER" || failure # Also it doesn't return good error code $TEST "$LOCAL" -nt "$CHGTEST" && success || ask_if_merged fi fi # Attempt to do a merge with $EDITOR if [ -n "$MERGE" -o -n "$DIFF3" ]; then echo "conflicts detected in $LOCAL" cp "$BACKUP" "$CHGTEST" $EDITOR "$LOCAL" || failure # Some editors do not return meaningful error codes # Do not take any chances $TEST "$LOCAL" -nt "$CHGTEST" && success || ask_if_merged fi # attempt to manually merge with diff and patch if [ -n "$DIFF" -a -n "$PATCH" ]; then (umask 077 && mkdir "$HGTMP") || { echo "Could not create temporary directory $HGTMP" 1>&2 failure } $DIFF -u "$BASE" "$OTHER" > "$HGTMP/diff" || : if $PATCH "$LOCAL" < "$HGTMP/diff"; then success else # If rejects are empty after using the editor, merge was ok $EDITOR "$LOCAL" "$LOCAL.rej" || failure $TEST -s "$LOCAL.rej" || success fi failure fi echo echo "hgmerge: unable to find any merge utility!" echo "supported programs:" echo "merge, FileMerge, tkdiff, kdiff3, meld, diff+patch" echo failure