Tymczasowo odłożyć nieprzewidziane zmiany w Subversion (a la " git-stash")

Podczas programowania oprogramowania przechowywanego w Subversion repo, często modyfikuję niektóre pliki, a następnie zauważam, że chciałbym dokonać pewnych zmian przygotowawczych do mojej głównej pracy. Np. podczas implementacji nowej funkcjonalności zauważam pewne refaktoryzacje, które mogą mi pomóc.

Aby nie mieszać dwóch niezwiązanych ze sobą zmian, w takich przypadkach chciałbym "schować" moje zmiany, tzn. powrócić do wersji repozytorium, zrobić kilka innych zmian, zatwierdzić je, a następnie "odzyskać" moje zmiany.

Git-stash pozwala na to. Czy jest jakiś sposób, aby to zrobić z Subversion, bezpośrednio lub za pomocą wtyczki lub skryptu. Pluginy Eclipse również byłyby w porządku.

Author: Cœur, 0000-00-00

15 answers

Kiedy mam niezarejestrowane zmiany z jednego zadania w mojej kopii roboczej i muszę przełączyć się na inne zadanie, robię jedną z dwóch rzeczy:

  1. Sprawdź nową kopię roboczą drugiego zadania.

    Lub

  2. Uruchom gałąź:

    workingcopy$ svn copy CURRENT_URL_OF_WORKING_COPY SOME_BRANCH
    workingcopy$ svn switch SOME_BRANCH
    workingcopy$ svn commit -m "work in progress"
    workingcoyp$ svn switch WHATEVER_I_WAS_WORKING_ON_BEFORE
    

Mam kilka skryptów, które pomogą to zautomatyzować.

 66
Author: bendin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-06-08 10:38:44

Ten wpis na blogu radzi używać Diffa i patcha.

  • git stash w przybliżeniu staje się svn diff > patch_name.patch; svn revert -R .
  • git stash apply staje się patch -p0 < patch_name.patch

Zauważ, że to nie przechowuje zmian metadanych lub (myślę) katalog tworzy/usuwa. (Tak, svn śledzi je oddzielnie od zawartości katalogu, w przeciwieństwie do Gita.)

 303
Author: Walter Mundt,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-08-02 19:22:41

Możesz zapisać bieżące zmiany za pomocą svn diff do pliku poprawki, a następnie przywrócić kopię roboczą:

svn diff > stash.patch
svn revert -R .

Po zaimplementowaniu funkcji przygotowawczej możesz zastosować łatkę za pomocą narzędzia patch:

patch < stash.patch

Jak zauważyli inni, nie będzie to działać z operacjami svn:properties i tree (dodawanie, usuwanie, zmiana nazw plików i katalogów).

Pliki binarne też mogą dawać problemy, Nie wiem jak patch (lub TortoiseSVN w tym przypadku sobie z nimi radzi).

 162
Author: knittl,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-10-10 08:43:01

Najprostszym sposobem byłoby użycie tymczasowej gałęzi, jak to:

$ svn copy ^/trunk ^/branches/tempbranch
$ svn switch ^/branches/tempbranch
$ svn commit -m "Stashed"
$ svn switch ^/trunk
$ ... hack away in trunk ...
$ svn commit -m "..."
$ svn merge ^/branches/tempbranch .
$ svn rm ^/branches/tempbranch
$ ... continue hacking

To mogłoby (i prawdopodobnie powinno) być umieszczone w skrypcie, jeśli robi się to bardziej regularnie.

 39
Author: JesperE,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-10-12 12:34:47

Od 2018-04-13 (Subversion 1.10.0), masz experimental svn shelve polecenie . (TortoiseSVN obsługuje polecenie )

Obecnie jest tylko pomocnikiem do zapisania poprawki i zastosowania z powrotem, więc ma takie same ograniczenia jak svn diff + patch (tzn. nie może obsługiwać plików binarnych i zmieniać nazw). (Edit: wygląda na to, że wsparcie binarne pojawi się w następnej wersji )

$ svn shelve --help
x-shelve (shelve): Put a local change aside, as if putting it on a shelf.
usage: 1. x-shelve [--keep-local] NAME [PATH...]
       2. x-shelve --delete NAME
       3. x-shelve --list

  1. Save the local change in the given PATHs to a patch file, and
     revert that change from the WC unless '--keep-local' is given.
     If a log message is given with '-m' or '-F', include it at the
     beginning of the patch file.

  2. Delete the shelved change NAME.
     (A backup is kept, named with a '.bak' extension.)

  3. List shelved changes. Include the first line of any log message
     and some details about the contents of the change, unless '-q' is
     given.

  The kinds of change you can shelve are those supported by 'svn diff'
  and 'svn patch'. The following are currently NOT supported:
     mergeinfo changes, copies, moves, mkdir, rmdir,
     'binary' content, uncommittable states

  To bring back a shelved change, use 'svn x-unshelve NAME'.

  Shelved changes are stored in <WC>/.svn/shelves/

  The shelving feature is EXPERIMENTAL. This command is likely to change
  in the next release, and there is no promise of backward compatibility.

Valid options:
  --delete                 : delete the shelved patch
  --list                   : list shelved patches
  -q [--quiet]             : print nothing, or only summary information
  --dry-run                : try operation but make no changes
  --keep-local             : keep path in working copy
(...)

$ svn unshelve --help
x-unshelve (unshelve): Bring a shelved change back to a local change in the WC.
usage: 1. x-unshelve [--keep-shelved] [NAME]
       2. x-unshelve --list

  1. Apply the shelved change NAME to the working copy.
     Delete the patch unless the '--keep-shelved' option is given.
     (A backup is kept, named with a '.bak' extension.)
     NAME defaults to the most recent shelved change.

  2. List shelved changes. Include the first line of any log message
     and some details about the contents of the change, unless '-q' is
     given.

  Any conflict between the change being unshelved and a change
  already in the WC is handled the same way as by 'svn patch',
  creating a 'reject' file.

  The shelving feature is EXPERIMENTAL. This command is likely to change
  in the next release, and there is no promise of backward compatibility.

Valid options:
  --keep-shelved           : do not delete the shelved patch
  --list                   : list shelved patches
  -q [--quiet]             : print nothing, or only summary information
  --dry-run                : try operation but make no changes
(...)
 9
Author: snipsnipsnip,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-06-05 06:25:08

Nie znam łatwego sposobu, aby to zrobić tylko z svn. Szczerze mówiąc, radzę użyć git-svn, aby zrobić repo git, które działa jak kopia robocza svn, i po prostu użyć git stash z tym. Po prostu zamień git pull na git svn rebase i git push na git svn dcommit, a będziesz mógł zachować 90% przepływu pracy Gita i nadal rozmawiać z serwerem svn.

 7
Author: Walter Mundt,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-08-02 19:18:39

Istnieje mały skrypt Pythona 2 o nazwie svn-stash dostępny na licencji GPL 3: https://github.com/frankcortes/svn-stash .

Działa tak jak wspomniane rozwiązania svn diff/patch i oferuje pchanie i popping zmian jako diffów do jakiegoś lokalnego katalogu. Niestety, stashów nie można nazwać, a tylko ostatni może być popped (no tak, to stack, ale nie ma prawdziwego powodu do takiego ograniczenia.) Ale wtedy zawsze można było wbudować brakujące funkcje w źródło.

Jest napisany dla * ix, ale po zastąpieniu każdego " / " przez os.sep działa również dobrze pod Windows.

Jeśli używasz svn 1.7 lub wyższego, musisz zmienić is_a_current_stash(): usuń linię if ".svn" in os.listdir(CURRENT_DIR):, ponieważ jest tylko jeden najwyższy poziom .svn subdir in 1.7 WC ' s.

 4
Author: cxxl,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-06-14 16:56:54

Możesz to zrobić łatwo używając Intellij IDEA- Shelve Changes

 4
Author: lili,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-06-02 13:27:41

Inną opcją jest skopiowanie aktualnej kasy do nowego katalogu i przywrócenie wszystkich zmian. w ten sposób zaoszczędzisz kłopotów związanych z tworzeniem tymczasowej gałęzi na serwerze-w końcu stashing jest operacją lokalną, którą nie każdy powinien widzieć i można ją wykonywać dość często.

Po zatwierdzeniu poprawki możesz zaktualizować swoją główną kopię roboczą i usunąć "obszar przechowywania"

 3
Author: knittl,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-10-12 19:03:18

Ja również chciałem tę funkcję. Obecnie używam TortoiseSVN.

Nie znalazłem twardego rozwiązania poza eksportem drzewa, przywróceniem z powrotem do repozytorium wykonaj moje zmiany i zatwierdź, a następnie porównaj zmiany z wyeksportowanego drzewa z powrotem do mojego kontrolowanego katalogu źródłowego za pomocą narzędzia takiego jak Beyond Compare.

Lub innym rozwiązaniem może być rozgałęzianie się z HEAD do innego katalogu, wprowadzanie zmian i commit. Gdy będziesz gotowy, aby połączyć je z powrotem do swojego drugiego kopia robocza, wykonaj aktualizację i scal zmiany.

 1
Author: Anthony Shaw,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-10-12 12:30:07

Zawsze trzymam drugi checkout, który nazywam "trunk_clean". Ilekroć muszę zrobić szybką, odosobnioną zmianę związaną z tym, co robię, po prostu zobowiązuję się do tej kasy.

 1
Author: angularsen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-07-12 14:16:46

[1]}powyższe pomysły na rozgałęzianie i łatanie są świetne, ale nie działają dobrze dla mnie. Używam wizualnego narzędzia do różnicowania, więc uruchamianie git diff nie powoduje tworzenia łatek tekstowych. Nasz system budowania uruchamia nowe środowisko za każdym razem, gdy tworzona jest gałąź, więc tworzenie tymczasowych gałęzi "stash" robi się brudne.

Zamiast tego napisałem mały skrypt powłoki, który kopiuje plik do katalogu "półka", dodaje znacznik czasu i cofa zmianę. Nie jest tak wytrzymały jak powyższe rozwiązania, ale unika też pułapek, na które wpadłem.

 0
Author: Ryan DeBeasi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-09-15 18:28:44

Na podstawie odpowiedzi Waltera utworzyłem w moim pliku bashrc następujące aliasy:

alias svn.stash='read -p "saving local changes in raq.patch. Existing stash in raq.patch will be overwritten. Continue?[y/N]" && [[ $REPLY =~ ^[yY] ]] && rm -f raq.patch && svn diff > raq.patch && svn revert -R .'
alias svn.stash.apply='patch -p0 < raq.patch; rm -f raq.patch'

Te aliasy są znacznie łatwiejsze w użyciu i zapamiętaniu.

Użycie:

svn.stash to stash changes I svn.stash.apply to apply stash.

 0
Author: Raheel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-03-12 09:47:09

Użycie:

svn cp --parents . ^/trash-stash/my-stash

Utworzy gałąź z bieżącej lokalizacji i bieżącej wersji, a następnie zatwierdzi zmiany w kopii roboczej do tej gałęzi bez przełączania się na nią.

Użycie: skopiuj SRC [@REV]... DST

SRC i DST mogą być zarówno ścieżką do kopii roboczej (WC), jak i adresem URL:

WC  -> URL:  immediately commit a copy of WC to URL

Zauważ, że zmiany w kopii roboczej nie zostaną automatycznie cofnięte (cp to tylko kopiowanie zmian do nowej gałęzi) i musisz cofnąć ręcznie.

Aby przywrócić zmiany, możesz po prostu scalić zmiany z nowo utworzonej gałęzi do swojej kopii roboczej.

svn merge --ignore-ancestry ^/trash-stash/my-stash -c <commited revision>

--ignore-ancestry jest używany, aby nie aktualizować informacji scalania w kopii roboczej.

Użycie:

svn ls -v ^/trash-stash/

Aby zobaczyć, co masz na ścieżce skrytki. Drukowane są również zatwierdzone wersje.

Jeśli nie potrzebujesz już skrytki, po prostu uruchom:

svn rm ^/trash-stash/my-stash

To rozwiązanie jest lepsze niż użycie patcha w tym, że jeśli nowe zmiany w kopii roboczej lub na bieżącym konflikt gałęzi ze zmianami w skrytce, można rozwiązać konflikty za pomocą środków svn, podczas gdy patch w niektórych przypadkach po prostu zawiedzie lub nawet zastosuje łatkę nieprawidłowo.

 0
Author: anton_rh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-06-13 11:46:05

W mojej praktyce używam git init do tworzenia repozytorium Git w trunk katalogu mojego repozytorium Subversion, a następnie dodaję *.git do wzorców suctions ignore.

Po modyfikacji niektórych plików, jeśli chcę kontynuować pracę z linią główną Subversion, po prostu używam git stash, aby ukryć swoją pracę. Po zalogowaniu się do repozytorium Subversion używam git stash pop, aby przywrócić moje modyfikacje.

 -2
Author: yhluo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-06-08 10:51:11