Subversion, отметьте файл, удаленный или перемещенный после факта

Скажем, что у меня есть два файла в репозитории Subversion:

workingcopy/
  file1.txt
  file2.txt

И затем я переименовываю одно, внешнее SVN:

$ mv file1.txt fileA.txt

Теперь SVN отмечает файл file1.txt как отсутствующий, fileA.txt как неверсифицированный

$ svn st
!   file1.txt
?   fileA.txt

Насколько известно SVN, я удалил file1.txt и создал совершенно другой файл fileA.txt, поэтому он не будет знать, как отслеживать изменения между файлами.


EDIT: это действительно работает, я просто не могу правильно записать имена файлов:)

Аналогично, если вы удалите файл

$ rm file2.txt
$ svn st
!   file2.txt

SVN знает только, что файл пропал без вести, и попытка удалить его не работает: Забастовкa >

$ svn remove file2.txt
svn: 'file2.txt' does not exist

Я знаю, что в Mercurial вы можете пометить файл как перемещенный, скопированный, удаленный и т.д. после факта с флагом --after, независимо от того, что Mercurial видит в рабочей копии.

Есть ли аналогичный трюк в SVN?

Ответы

Ответ 1

Возможно, вам нужно обновить версию Subversion:

$ svn --version
svn, version 1.6.16 (r1073529)

$ rm data.xml

$ svn status
!       data.xml

$ svn rm data.xml
D       data.xml

$ svn status
D       data.xml

То же самое не работает с переименованием, но было бы очень легко написать оболочку script, которая делает это:

#!/bin/sh

mv $2 $1
svn rename $1 $2

Или просто для удовольствия вы можете добавить следующее в свой .bashrc или .bash_profile:

svn_mv_after() 
{
        mv $2 $1
        svn mv $1 $2
}

alias svnmva=svn_mv_after

Ответ 2

Если вы используете TortiseSVN, вы можете сделать это на экране фиксации. Щелкните правой кнопкой мыши на удаленном и добавленном файле (тот же файл, только что перемещенный) вместе вы получите возможность отремонтировать ход.

http://tortoisesvn.net/repairmoves.html

Ответ 3

Нет SVN нет такой вещи, потому что вы оставите SVN с помощью команды "mv.." вместо "svn mv..." для "rm...", это тоже самое...

SVN следует именам файлов с содержимым метаинформации, тогда как в git, hg и bzr содержимое сопровождается именем файла метаинформации. Вот почему вы можете делать что-то в git, hg (я не знаю), bzr (я тоже не знаю), если вы можете использовать команды операционной системы для переименования и удаления файлов.

Что вы можете сделать после того, как узнали, что что-то пропустили... например, если вы случайно удалили файл:

svn revert deleted.file.ext

svn rm deleted.file.ext

В случае переименования файла вы можете сделать это только в том случае, если вы ничего не изменили в новом файле, после чего вы переименовали его в

mv file1.txt fileA.txt

вы можете сделать то же самое

svn revert file1.txt

сначала удалите файлA.txt, а затем

svn mv file1.txt fileA.txt

Если вы что-то изменили в переименованном файле (fileA.txt), просто сделайте копию этого файла и выполните ту же процедуру и замените содержимое файла после "svn mv..."

Ответ 4

Я запускаю Arch Linux и имею следующее в .bashrc. Он может обрабатывать новый файл, находящийся в местоположении, в котором вы перемещали исходный код, и должен иметь возможность принимать самые странные пути (например, начиная с тире или содержащих пробелы). Вам нужно установить realpath.

svma() {
    local dst src tmp

    # Check arguments
    if [[ $# != 2 ]]; then
        echo 'Usage: svma SRC DST'
        return 1
    fi

    # Ensure paths start with a slash, not a dash
    src=$(realpath -- "$1")
    dst=$(realpath -- "$2")

    # If there is a new file at the path of the source, move it to a
    # temporary name in the same directory
    if [[ -e "$src" ]]; then
        tmp=$(mktemp "--tmpdir=$(dirname "$src")" -u)
        mv "$src" "$tmp"
    fi

    # Restore the source and then have Subversion move it
    mv "$dst" "$src"
    svn mv "$src" "$dst"

    # If required, move the new file back to the source path
    if [[ -v tmp ]]; then
        mv "$tmp" "$src"
    fi
}

Ответ 5

Я скорректировал решение @Peter Sutton немного для обработки случаев, когда каталог для SRC отсутствовал, каталог для DST еще не был версией и взял необязательный третий параметр FILE, если источник и назначение имена файлов одинаковы (если указано FILE, SRC и DST - это каталоги). Опять же, realpath необходим, и я тестировал это только в Cygwin с версией SVN версии 1.8.11. Резервное копирование обрабатывается с помощью mv -b, который будет clobber любого файла в $src~, и любые нежелательные каталоги, созданные mkdir, нужно будет удалить вручную.

svma() {
    local dst src tmp

    # Check arguments
    if [[ ( $# != 2 ) && ( $# != 3 ) ]]; then
        echo 'Usage: svma SRC DST [FILE]'
        return 1
    fi

    # Ensure paths start with a slash, not a dash
    src=$(realpath -- "$1")
    dst=$(realpath -- "$2")

    if [[ $# == 2 ]]; then
        srcdir=$(dirname "$src")
        dstdir=$(dirname "$dst")
    else
        srcdir="$src"
        dstdir="$dst"
        src="$srcdir/$3"
        dst="$dstdir/$3"
    fi

    mkdir -p "$srcdir"
    svn add "$dstdir" --parents --depth=empty --force

    # Restore the source and then have Subversion move it
    mv -b "$dst" "$src"
    svn mv "$src" "$dst"

    # If required, move the backed-up file back to the source path
    if [[ -e "$src~" ]]; then
        mv "$src~" "$src"
    fi
}