Subversion에서 커밋되지 않은 변경 사항을 일시적으로 제거하십시오 ( "git-stash")


312

Subversion 저장소에 저장된 소프트웨어를 프로그래밍하는 동안 종종 일부 파일을 수정 한 다음 주요 작업을 위해 준비 변경을하고 싶습니다. 예를 들어 새로운 기능을 구현하는 동안 리팩터링이 도움이 될 수 있습니다.

관련이없는 두 가지 변경 사항을 혼합하지 않기 위해 이러한 경우에는 변경 사항을 "버려두고"즉, 리포지토리 버전으로 되돌리고 다른 변경을 수행 한 다음 커밋 한 다음 변경 내용을 "반입"하고 싶습니다.

git-stash 는 그렇게 할 수 있습니다. Subversion에서 직접 또는 일부 플러그인 또는 스크립트를 사용 하여이 작업을 수행 할 수있는 방법이 있습니까? 이클립스 플러그인도 좋습니다.


6
그냥 궁금하지만 git-svn을 사용하지 않는 이유는 무엇입니까?
cmcginty

3
관련 뉴스 : infoworld.com/d/application-development/… (견적 : "그는 또한 곧 출시 될 Subversion 1.8 릴리스가 Git 숨김과 같은 기능을 통해 Git의 기능에 더 가까이 다가 갈 것이라고 언급합니다. 개발자는 로컬로 변경할 수 있습니다. 오프라인 커밋-개발자가 오프라인 일 때 완료된 변경 사항을 기록하고 개발자가 다시 연결될 때 마스터 저장소로 이동합니다. "
Sebastiaan van den Broek

1
업데이트 (2012-04-26 기준) : 선반은 이제 ETA없이 1.9로 예정되어 있습니다. 그래서 시간이 좀 걸릴 수 있습니다 ...
sleske

10
업데이트 (2012-11-17 기준) : 선반은 이제 1.10으로 예정되어 있습니다. 어쩌면 항상 <다음 릴리스 +1>으로 예정되어 있습니까? ;-)
sleske

3
업데이트 (2015-03-23, 2 년 반 후) : 좋은 소식은 선반 선반이 여전히 1.10으로 예정되어 있다는 것입니다. 나쁜 소식은 ETA : 2015 년 2 분기 (가칭) 릴리스 1.9.0 / 2017입니까? (추론 최고) 릴리스 1.10.0 ( subversion.apache.org/roadmap.html )
ribamar

답변:


69

작업 사본의 한 작업에서 커밋되지 않은 변경 사항이 있고 다른 작업으로 전환해야하는 경우 다음 두 가지 중 하나를 수행합니다.

  1. 두 번째 작업에 대한 새 작업 복사본을 확인하십시오.

    또는

  2. 지점을 시작하십시오.

    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
    

이것을 자동화하는 데 도움이되는 스크립트가 있습니다.


65
이것은 당신의 서브 버전 서버에 많은 쓰레기를 초래할 것입니다
knittl

3
@knittl : 아뇨. 그리고 더 중요한 것은 : 제안과 마찬가지로 변경 사항이 손실되지는 않습니다. 이것은 트렁크 / 같은 지점의 다른 체크 아웃 사본을 갖는 것이 내가 아는 유일한 두 가지 확실한 방법입니다. 이 방법이 불편한 경우 다른 사본을 확인하고 동시에 작업하십시오.
sbi

2
@knittl : 브랜치는 프로젝트의 기본 브랜치 또는 태그 위치 밖에있는 눈에 띄지 않는 경로로 만들 수 있습니다. 예를 들어 팀은 이러한 목적으로 project\temp\<creationdate-reason>또는 project\personal\<creationdate-reason>이를 지정할 수 있습니다 .
rwong

12
여전히 서버에 지점을 만들어야한다는 것은 불행한 일입니다. 그러한 브랜치가 많은 양의 데이터를 복제하는 것이 아니라 git와 같은 시스템이 필요없는 많은 불필요한 참조를 생성합니다.
theeper

8
큰 저장소에서는 유용하지 않습니다. 이것은 내 작업 환경에서 절대 옵션이 아닙니다. 그리고 우리 저장소가 더 작고 체계적으로 구성되고 svn 대신 git 저장소가 솔직히 바란다면 나는 조직에서 코드가 구성되는 방식의 한계에 국한되어 있습니다.
AdrianVeidt 2016 년

337

이 블로그 게시물 은 diff 및 patch 사용을 권장합니다.

  • git stash 대략적으로 svn diff > patch_name.patch; svn revert -R .
  • git stash apply 된다 patch -p0 < patch_name.patch

이것은 메타 데이터 변경 사항을 숨기거나 디렉토리가 생성 / 삭제되지 않는다는 점에 유의하십시오. (예, svn은 git과 달리 디렉토리 내용과 별도로 추적합니다.)


13
이것은 실수로 stackoverflow.com/questions/1554278/…의 중복입니다 .
Walter Mundt

2
또한 바이너리 파일을 포함하지 않는 것 같습니다. 적어도 TortoiseSVN을 사용하여 패치를 생성 할 때.
angularsen


6
메타 데이터 가 패치 파일에 있고 svn 패치가이를 이해하기 때문에 메타 데이터 svn patch patch_name.patch대신에 메타 데이터를 추적 할 수 patch -p0있습니다.
mat

외부 변경 사항은 포함되지 않습니다.
congusbongus

182

현재 변경 사항을 svn diff패치 파일에 저장 한 다음 작업 사본을 되돌릴 수 있습니다.

svn diff > stash.patch
svn revert -R .

준비 기능을 구현 한 후 patch 유틸리티를 사용하여 패치를 적용 할 수 있습니다.

patch < stash.patch

다른 사람들이 언급했듯이 이것은 svn:properties트리 작업 (파일 및 디렉토리 추가, 제거, 이름 바꾸기)에서 작동 하지 않습니다 .

이진 파일도 문제를 일으킬 수 있습니다. 패치 (또는이 경우 TortoiseSVN이 처리하는 방법)를 모르겠습니다.


4
이것은 아마도 제거되거나 이름이 바뀐 파일에서 제대로 작동하지 않을 것이라고 생각합니다.
JesperE

7
"패치를 대신 사용하지 않는 이유"상자를 참조하십시오. 에 svnbook.red-bean.com/en/1.5/... 이 나쁜 생각 왜 이해합니다.
sbi

4
@ sbi : 나는 그것이 downvote에 대한 정당한 정당화라고 생각하지 않습니다. "나쁜 대답"이 아닙니다. 완벽한 답변은 아닙니다. 나는이 사람이 그의 제안에 대해 형벌을받을 자격이 없다고 생각한다. 대신 대답하지 않으시겠습니까? 그렇다면, 예, 공감해야합니다. 그렇지 않으면 이것은 좋은 의도를 처벌하는 것입니다.
Sedat Kapanoglu

5
경우 다른 사람에, 나 같은, 가벼운 무게 솔루션 등이 모습을 생각하고 그것을 시도하기로 결정, 나는 패치를 사용했다 -p0 <stash.patch - 그렇지 않으면에 대한 패치 파일을 찾을 수 없다는 불평
CupawnTae

4
이 조언은 git 배경에서 왔으며 다양한 이유로 인해 SVN을 사용해야하는 경우에 특히 도움이됩니다. 패치를 처음 사용하는 사용자에게 제공되는 조언이 약간 개선되었습니다 $ patch --strip=0 < stash.patch . 패치를 적용 할 때 패치가 파일 이름을 묻지 않도록합니다.
ksinkar

43

가장 쉬운 방법은 다음과 같이 임시 분기를 사용하는 것입니다.

$ 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

좀 더 정기적으로 수행하면 스크립트에 넣을 수 있습니다.


2
파일을 삭제 / 추가하거나 속성을 변경 한 경우에도 작동하지 않는 "솔루션"이 투표되는 이유는 무엇입니까? 예, 처음 할 때 가장 쉬운 방법은 아니지만 다른 사본이 동시에 작동하도록 체크 아웃하는 것 외에도 모든 경우에 적합한 유일한 솔루션입니다.
sbi

5
repo root에 대해 ^ 구문을 잘 사용합니다 (svn 1.6부터). 리포지토리에 트렁크 / 태그 / 브랜치가 최상위 수준에있을 때 좋은 솔루션입니다.
bendin

4
나는이 모든 임시 브랜치를 서버에 두는 것을 정말로 좋아하지 않는다. 서버를 복잡하게 만드는 대신 로컬에서 수행해야한다고 생각합니다 (체크 인 할 때 메일을 생성하는 경우 spurios 체크인 이메일 생성). 여전히 기억할 가치가있는 옵션입니다.
sleske

3
@ sleske : 예, 임시 숨김을 서버에 커밋하고 있지만 지점 자체는 삭제됩니다. 어쨌든 이것이 가장 빠르고 강력한 방법이라고 생각합니다.
JesperE

5
@ sleske : SVN은 분산 VCS가 아니므로 모든 것이 서버에 있어야합니다. 그것이 바로 그 방법입니다.
sbi

24

1.10.0 (2018-04-13) 현재 실험 svn shelve명령이 있습니다. ( TortoiseSVN은 명령을 지원합니다. ) 패치를 저장하고 다시 적용하는 데 도움이 될 뿐이므로 svn diff+ 와 같은 제한이 patch있습니다 (즉, 이진 파일을 처리하고 이름을 바꿀 수 없음). ( 편집 : 바이너리 지원이 다음 버전 1.11.0에서 제공되는 것 같습니다 )

편집 ^ 2 : 1.11.0 (2018-10-30 릴리스)에서는 이진 파일이 지원됩니다 . 선반 이름이 바뀐 파일은 지원되지 않습니다. 1.11의 선반은 1.10에서 만든 선반과 호환되지 않습니다.

편집 ^ 3 : 1.12.0 (2019-04-24 릴리스)에서는 복사 및 이름 바꾸기가 지원됩니다 . 1.12의 선반은 이전 버전에서 만든 선반과 호환되지 않습니다.

편집 ^ 4 : 1.13.01.14.0 으로 선반을 바꾸는 데 변화가 없습니다 . 명령은 여전히 ​​실험으로 표시되어 SVN_EXPERIMENTAL_COMMANDS=shelf3있으며 기능을 사용 하도록 정의해야 합니다. 기능이 현재 심사되지 않은 것 같습니다 .

설계 노트는 개발자의 Wiki 에서 찾을 수 있습니다 .

$ svn x-shelve --help
x-shelve: Move local changes onto a shelf.
usage: x-shelve [--keep-local] SHELF [PATH...]

  Save the local changes in the given PATHs to a new or existing SHELF.
  Revert those changes from the WC unless '--keep-local' is given.
  The shelf's log message can be set with -m, -F, etc.

  'svn shelve --keep-local' is the same as 'svn shelf-save'.

  The kinds of change you can shelve are committable changes to files and
  properties, except the following kinds which are not yet supported:
     * copies and moves
     * mkdir and rmdir
  Uncommittable states such as conflicts, unversioned and missing cannot
  be shelved.

  To bring back shelved changes, use 'svn unshelve SHELF'.

  Shelves are currently stored under <WC>/.svn/experimental/shelves/ .
  (In Subversion 1.10, shelves were stored under <WC>/.svn/shelves/ as
  patch files. To recover a shelf created by 1.10, either use a 1.10
  client to find and unshelve it, or find the patch file and use any
  1.10 or later 'svn patch' to apply it.)

  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:
  -q [--quiet]             : print nothing, or only summary information
  --dry-run                : try operation but make no changes
  --keep-local             : keep path in working copy

(...)

$ svn x-unshelve --help
x-unshelve: Copy shelved changes back into the WC.
usage: x-unshelve [--drop] [SHELF [VERSION]]

  Apply the changes stored in SHELF to the working copy.
  SHELF defaults to the newest shelf.

  Apply the newest version of the shelf, by default. If VERSION is
  specified, apply that version and discard all versions newer than that.
  In any case, retain the unshelved version and versions older than that
  (unless --drop is specified).

  With --drop, delete the entire shelf (like 'svn shelf-drop') after
  successfully unshelving with no conflicts.

  The working files involved should be in a clean, unmodified state
  before using this command. To roll back to an older version of the
  shelf, first ensure any current working changes are removed, such as
  by shelving or reverting them, and then unshelve the desired version.

  Unshelve normally refuses to apply any changes if any path involved is
  already modified (or has any other abnormal status) in the WC. With
  --force, it does not check and may error out and/or produce partial or
  unexpected results.

  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:
  --drop                   : drop shelf after successful unshelve
(...)

$ svn help | grep x-
 x-shelf-diff
 x-shelf-drop
 x-shelf-list (x-shelves)
 x-shelf-list-by-paths
 x-shelf-log
 x-shelf-save
 x-shelve
 x-unshelve

9

svn으로 쉽게 수행 할 수있는 방법을 모르겠습니다. 솔직히 git-svnsvn 작업 복사본으로 작동하는 git repo를 작성 git stash하고 그와 함께 사용 하는 것이 좋습니다. 와 함께 교체 git pull하고 교체 하면 실제로 git 워크 플로우의 90 %를 유지하고 여전히 svn 서버와 통신 할 수 있습니다.git svn rebasegit pushgit svn dcommit


그러나 위의 의견에서 언급 한 링크 stackoverflow.com/questions/1554278/… svn에서만 숨김을 수행하는 실용적인 솔루션을 제안합니다.
VonC

그럴 수 있지; 실제로 Google은 지금 블로그에서 해당 솔루션으로 안내합니다. 나는이 질문자에게 git-svn이 자연스러운 해결책이라고 여전히 유지합니다.
Walter Mundt

git은 그렇지 않기 때문에 솔루션이 파일 이름 바꾸기를 따르는 지 의심합니다.
NO_NAME

4

svn-stashGPL 3 : https://github.com/frankcortes/svn-stash 에서 사용할 수 있는 작은 Python 2 스크립트가 있습니다 .

그것은 svn diff/patch언급 된 솔루션 과 같이 작동 하며 일부 로컬 디렉토리에 차이점으로 변경 사항을 푸시하고 터지는 것을 제공합니다. 불행히도, 숨김은 이름을 지정할 수 없으며 마지막 것만 튀어 나올 수 있습니다 (예, 스택이지만 그러한 제한에 대한 실제 이유는 없습니다.) 그러나 항상 누락 된 기능을 출처.

* ix 용으로 작성되었지만 모든 "/"를 바꾸면 os.sepWindows에서도 잘 작동합니다.

svn 1.7 이상을 사용하는 경우 1.7 WC에는 최상위 .svn 하위 디렉토리가 하나만 있으므로 is_a_current_stash()line을 제거 해야합니다 if ".svn" in os.listdir(CURRENT_DIR):.


창문 아래에서 나를 위해하지 않습니다! :(
Antonio Petricca

4

Intellij IDEA- Shelve Changes를 사용하여 쉽게 할 수 있습니다.


이 방법은 처리 할 수 있는가 metadata changesdirectory creates/deletes? 정확히 무엇을 git stash합니까?
wonsuc

3

다른 옵션은 현재 체크 아웃을 새 디렉토리에 복사하고 모든 변경 사항을 되 돌리는 것입니다. 이렇게하면 서버에 임시 브랜치를 생성하는 번거 로움을 줄일 수 있습니다. 모든 스 태싱이 로컬 작업이므로 모든 사람이 볼 수는없고 자주 수행 할 수있는 것은 아닙니다.

핫픽스를 커밋 한 후 기본 작업 복사본을 업데이트하고 "스태킹 영역"을 삭제할 수 있습니다


참고 : 이것은 두 번째 작업 복사본을 체크 아웃하는 것과 본질적으로 동일합니다.
sleske

6
@sleske : 예, 새로운 결제에 필요한 엄청난 양의 대역폭없이
knittl

좋든 싫든 이것은 "git stash"동작을보다 밀접하게 반영하는 답입니다. 브랜치를 생성하는 것은 멋지지만 TFS 선반과 관련이 있습니다.
찰스 로베르토 Canato

1

이 기능도 원했습니다. 현재 TortoiseSVN을 사용하고 있습니다.

트리를 내보내고 리포지토리로 되돌아 가서 변경하고 커밋 한 다음, Beyond Compare와 같은 도구를 사용하여 내 보낸 트리의 변경 사항을 소스 제어 디렉토리로 다시 비교하는 것 외에는 확실한 해결책을 찾지 못했습니다.

또는 다른 해결책은 HEAD에서 다른 디렉토리로 분기하고 변경하고 커밋하는 것입니다. 다른 작업 사본으로 다시 병합 할 준비가되면 업데이트를 수행하고 변경 사항을 병합하십시오.


1

나는 항상 "trunk_clean"이라고하는 두 번째 체크 아웃을 유지합니다. 내가하는 일과 관련하여 신속하고 고립 된 변경을 수행해야 할 때마다 대신 해당 체크 아웃을 커밋합니다.


0

위의 브랜칭 및 패치 아이디어는 훌륭하지만 나에게 적합하지 않습니다. 시각적 차이 도구를 사용하므로 git diff텍스트를 실행 해도 텍스트 기반 패치가 생성되지 않습니다. 우리의 빌드 시스템은 브랜치를 생성 할 때마다 새로운 환경을 가동 시키므로 임시 "스 태쉬"브랜치를 생성하는 것은 지저분해질 것입니다.

대신 파일을 "shelf"디렉토리에 복사하고 타임 스탬프를 추가 한 다음 변경 사항을 되 돌리는 작은 쉘 스크립트 를 작성했습니다. 위의 솔루션만큼 강력하지는 않지만 내가 만난 함정을 피합니다.


0

Walter의 답변에 따라 bashrc 파일에 다음과 같은 별칭을 만들었습니다.

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'

이 별칭은 사용하고 기억하기가 훨씬 쉽습니다.

용법:

svn.stash 는 숨김 변경 사항을, svn.stash.apply 는 숨김을 적용합니다.


0

실습에서는 Subversion 저장소의 디렉토리에 git initGit 저장소를 trunk만든 다음 *.git흡입 무시 패턴에 추가 합니다.

일부 파일을 수정 한 후 Subversion 메인 라인으로 작업을 계속하려면 git stash작업을 숨기려고 사용 합니다. Subversion 저장소에 커밋 한 후 git stash pop수정 사항을 복원 하는 데 사용 합니다.


2
이것은 실제로 좋은 해결책입니다! 다른 많은 솔루션은 타사 도구를 사용하여 문제를 해결합니다. 이 도구는 Git을 타사 도구로 사용합니다. 이것은 몇 가지 장점이 있습니다. 1) Git은 매우 일반적이며 강력합니다. 2) 많은 사람들이 이미 Git을 설치했습니다.
Lii

git commit을 수행하지 않으면 이것이 어떻게 작동하는지 궁금합니다.
B2K

0

사용하다:

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

현재 위치와 현재 개정판에서 분기를 만든 다음 전환하지 않고 해당 분기에 대한 작업 복사본의 변경 사항을 커밋합니다.

사용법 : 복사 SRC [@REV] ... DST

SRC 및 DST는 각각 작업 사본 (WC) 경로 또는 URL 일 수 있습니다.

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

작업 복사본에서의 변경은 자동으로 되돌릴 수 없습니다 것을 참고 ( cp그냥 복사하는 새로운 지점을 변경) 당신은 수동으로 되돌릴 수 있습니다.

변경 사항을 복원하려면 새로 만든 지점에서 작업 복사본으로 변경 내용을 병합하면됩니다.

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

--ignore-ancestry 작업 복사본에서 병합 정보를 업데이트하지 않기 위해 사용됩니다.

사용하다:

svn ls -v ^/trash-stash/

당신이 숨은 길에있는 것을 볼 수 있습니다. 확정 된 개정판도 인쇄됩니다.

더 이상 숨김이 필요하지 않으면 다음을 실행하십시오.

svn rm ^/trash-stash/my-stash

이 솔루션은 작업 복사본 또는 현재 분기의 새로운 변경 사항이 숨김의 변경 사항과 충돌 할 patch경우 svn 평균을 사용하여 충돌을 해결할 수있는 반면 패치의 경우 실패하거나 잘못 적용 하는 점에서 패치를 사용하는 것보다 낫습니다 .


-1

Subversion은 stash기능을 완벽하게 지원하지 않기 때문에
이와 같이 수동으로 수행합니다.

장소 DevelopmentProduction(release)분리 된 경로로 프로젝트.

source\code\MyApp         -- Development
release\MyApp(release)    -- Production(release)

개발 경로에서 프로젝트의 새로운 기능을 모두 사용할 수 있으며,
의미있는 진전을 이루기 만하면 안정을 위해 무언가를 발표해야합니다.

프로덕션 용으로 릴리스해야하는 경우 프로덕션 프로젝트를 열고 svn을 업데이트하고 릴리스 할 작업 (빌드, 내보내기 등)을 수행하십시오.

나는 이것이 약간 번거 롭다는 것을 알고 있지만 진보를 방출하는 것은 자주 일어나지 않습니다 (나에게는 그렇지 않지만 일부 프로젝트는 알고 있습니다).

프로젝트 팀 멤버가 사용하기 때문에 특정 프로젝트에 svn을 사용하고 있으므로 따라야합니다.
가장 좋은 솔루션은 git완벽한 버전 관리 시스템 을 사용 하는 것 svn입니다.


현재하고있는 일이 무엇인지 (명확한 디렉토리에서 어떤 버전이 체크 아웃 되었는가) 확실하지 않지만, 가장 인기있는 답변과 중복 된 것 같습니다 ( "새 작업 사본 확인").
sleske

@sleske 죄송합니다. 귀하의 케이스 세부 사항을 읽지 못했습니다. 내 경우에는, 난 단지 필요 dev하고 prod,이 상황을. 완전히 새로운 기능을 개발하려면 svn을 사용하는 것이 복잡합니다. svn 세계에서 사건을 해결할 명확한 방법이 있는지 확실하지 않습니다.
wonsuc 2015 년
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.