Tạm thời loại bỏ những thay đổi không được cam kết trong Subversion (một la git-stash ')


312

Trong khi phần mềm lập trình được lưu trữ trong một repo Subversion, tôi thường sửa đổi một số tệp, sau đó nhận thấy rằng tôi muốn thực hiện một số thay đổi chuẩn bị cho công việc chính của mình. Ví dụ, trong khi thực hiện chức năng mới, tôi nhận thấy một số cấu trúc lại có thể giúp tôi.

Để không trộn lẫn hai thay đổi không liên quan, trong những trường hợp này, tôi muốn "loại bỏ" các thay đổi của mình, tức là trở lại phiên bản kho lưu trữ, thực hiện một số thay đổi khác, cam kết những thay đổi này, sau đó "tìm lại" các thay đổi của tôi.

git-stash cho phép làm điều đó. Có một số cách để làm điều này với Subversion, trực tiếp hoặc với một số plugin hoặc tập lệnh. Các plugin Eclipse cũng sẽ ổn.


6
chỉ tò mò, nhưng tại sao không sử dụng git-svn?
cmcginty

3
Một số tin tức liên quan: infoworld.com/d/application-development/, (trích dẫn: "Ông cũng lưu ý rằng phiên bản Subversion 1.8 sắp tới sẽ đưa nó đến gần hơn với các khả năng của Git, với các tính năng như Git stash, trong đó nhà phát triển có thể thay đổi cục bộ và sau đó đặt chúng sang một bên và các cam kết ngoại tuyến, ghi lại các thay đổi đã hoàn thành khi nhà phát triển ngoại tuyến và chuyển sang kho lưu trữ chính khi nhà phát triển kết nối lại. "
Sebastiaan van den Broek

1
Cập nhật (kể từ 2012-04-26): Giá hiện được lên kế hoạch cho 1.9, không có bất kỳ ETA nào. Vì vậy, có thể mất một lúc ...
sleske

10
Cập nhật (kể từ 2012-11-17): Giá hiện được lên kế hoạch cho 1.10. Có lẽ nó luôn được lên lịch cho <bản phát hành tiếp theo +1>? ;-)
sleske

3
Cập nhật (kể từ 2015-03-23, 2 năm rưỡi sau): Tin vui là Shelving vẫn được lên kế hoạch cho 1.10. Tin xấu là ETA: Q2 2015 (dự kiến) Phiên bản 1.9.0 / 2017? (đầu cơ tốt nhất) Bản phát hành 1.10.0 ( subversion.apache.org/roadmap.html )
ribamar

Câu trả lời:


69

Khi tôi nhận được các thay đổi không được cam kết từ một nhiệm vụ trong bản sao làm việc của mình và tôi cần chuyển sang một nhiệm vụ khác, tôi thực hiện một trong hai điều sau:

  1. Kiểm tra một bản sao làm việc mới cho nhiệm vụ thứ hai.

    hoặc là

  2. Bắt đầu một chi nhánh:

    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
    

Tôi có một số kịch bản giúp tự động hóa việc này.


65
điều này sẽ dẫn đến rất nhiều rác trên máy chủ lật đổ của bạn
knittl

3
@knittl: Không, nó sẽ không. Và điều quan trọng hơn nữa: Nó sẽ không dẫn đến những thay đổi bị mất như đề xuất của bạn. Điều này, và có một bản sao khác được kiểm tra của thân cây / cùng chi nhánh, là hai cách duy nhất đáng tin cậy để làm điều này mà tôi biết. Nếu bạn cảm thấy không thoải mái với điều này, chỉ cần kiểm tra một bản sao khác và làm việc song song với nó.
sbi

2
@knittl: nhánh có thể được tạo trong một đường dẫn không rõ ràng nằm ngoài vị trí các nhánh hoặc thẻ mặc định của dự án. Ví dụ, một nhóm có thể chỉ định project\temp\<creationdate-reason>hoặc project\personal\<creationdate-reason>cho mục đích này.
rwong

12
Thật không may là chi nhánh phải được tạo trên máy chủ. Không phải các nhánh như vậy sao chép nhiều dữ liệu, mà chúng tạo ra rất nhiều tài liệu tham khảo không cần thiết mà một hệ thống như git không có.
thepeer

8
Điều này không hữu ích với một kho lưu trữ lớn. Điều này hoàn toàn không phải là một lựa chọn trong môi trường làm việc của tôi. Và trong khi tôi muốn kho lưu trữ của chúng tôi nhỏ hơn và được tổ chức tốt hơn, và thật lòng mà nói, một kho git thay vì svn, tôi bị giới hạn trong cách giới hạn mã được tổ chức trong tổ chức của chúng tôi.
AdrianVeidt

337

Bài đăng blog này tư vấn sử dụng diff và patch.

  • git stash xấp xỉ trở thành svn diff > patch_name.patch; svn revert -R .
  • git stash apply trở thành patch -p0 < patch_name.patch

Lưu ý rằng điều này không làm thay đổi siêu dữ liệu hoặc thư mục (tôi nghĩ) tạo / xóa. (Có, svn theo dõi chúng riêng biệt với nội dung thư mục, không giống như git.)


13
Đây là một bản sao ngẫu nhiên của stackoverflow.com/questions/1554278/ - - gửi upvotes ở đó.
Walter Mundt

2
Nó cũng dường như không bao gồm các tệp nhị phân, gây phiền nhiễu. Ít nhất là khi sử dụng TortoiseSVN để tạo bản vá.
angensesen

1
stackoverflow.com/questions/159853/ có thể giúp với điều đó.
Walter Mundt

6
Bạn có thể ít nhiều có siêu dữ liệu được theo dõi nếu bạn sử dụng svn patch patch_name.patchthay patch -p0vì bởi vì chúng nằm trong tệp vá và bản vá svn hiểu chúng.
chiếu

Điều này không bao gồm những thay đổi đối với bên ngoài.
congusbongus

182

Bạn có thể lưu trữ các thay đổi hiện tại của mình svn diffvào một tệp vá, sau đó hoàn nguyên bản sao làm việc của bạn:

svn diff > stash.patch
svn revert -R .

Sau khi bạn triển khai tính năng chuẩn bị của mình, bạn có thể áp dụng bản vá của mình với tiện ích vá:

patch < stash.patch

Như những người khác đã lưu ý rằng điều này sẽ không hoạt động với svn:propertiesvà các hoạt động của cây (thêm, xóa, đổi tên tệp và thư mục).

Các tệp nhị phân cũng có thể gây ra sự cố, tôi không biết cách vá (hoặc TortoiseSVN trong trường hợp này xử lý chúng).


4
Điều này có lẽ không hoạt động quá tốt với các tập tin bị xóa / đổi tên, tôi nghĩ vậy.
JesperE

7
Xem hộp có tiêu đề "Tại sao không sử dụng bản vá thay thế?" tại svnbook.red-bean.com/en/1.5/ trên để hiểu tại sao đây là một ý tưởng tồi.
sbi

4
@sbi: Tôi không nghĩ đó là một lời biện minh hợp lệ cho một downvote. Đó không phải là một "câu trả lời tồi". Đó không phải là câu trả lời hoàn hảo. Tôi không nghĩ người này đáng bị trừng phạt vì đề nghị của anh ta. Bạn có muốn anh ấy không trả lời thay thế? Nếu có, thì có, bạn nên downvote. Nếu không thì đây là trừng phạt ý tốt.
Sedat Kapanoglu

5
trong trường hợp bất kỳ ai khác, như tôi, nghĩ rằng đây giống như giải pháp nhẹ nhất và quyết định dùng thử, tôi đã phải sử dụng patch -p0 <stash.patch - nếu không thì nó đã phàn nàn về việc không thể tìm thấy các tệp để vá
CupawnTae

4
Lời khuyên này đặc biệt hữu ích nếu bạn đến từ nền git và buộc phải sử dụng SVN vì nhiều lý do. Một cải tiến nhỏ trong lời khuyên đã được đưa ra cho người dùng lần đầu sử dụng bản vá: $ patch --strip=0 < stash.patch Điều này sẽ đảm bảo rằng bản vá không hỏi bạn tên tệp khi bạn đang áp dụng bản vá.
ksinkar

43

Cách dễ nhất là sử dụng một nhánh tạm thời, như thế này:

$ 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

Điều này có thể (và có lẽ nên) được đưa vào một kịch bản nếu được thực hiện trên cơ sở thường xuyên hơn.


2
Tại sao điều này được bỏ phiếu, trong khi "giải pháp" được bỏ phiếu thậm chí không hoạt động khi bạn đã xóa / thêm tệp hoặc đã thay đổi bất kỳ thuộc tính nào? Đúng, đây không phải là việc dễ làm nhất khi bạn làm lần đầu tiên, nhưng, ngoài việc có một bản sao khác được kiểm tra để hoạt động song song, đây là giải pháp duy nhất hoạt động trong mọi trường hợp.
sbi

5
Sử dụng tốt cú pháp ^ cho repo root (kể từ svn 1.6). Giải pháp tốt khi repo của bạn có thân cây / thẻ / chi nhánh ở cấp cao nhất.
uốn cong

4
Tôi thực sự không thích đưa tất cả các nhánh tạm thời này lên máy chủ. Tôi cảm thấy việc này nên được thực hiện cục bộ, thay vì làm lộn xộn máy chủ (và tạo email kiểm tra spurios, nếu bạn tạo thư khi đăng ký). Tuy nhiên, một lựa chọn đáng nhớ.
sleske

3
@sleske: vâng, bạn đang cam kết tạm thời của mình với máy chủ, nhưng chính chi nhánh đã bị xóa. Dù sao, tôi nghĩ rằng đây là cách nhanh nhất và mạnh mẽ nhất để làm điều đó.
JesperE

5
@sleske: SVN không phải là một VCS phân tán, vì vậy mọi thứ phải có trên máy chủ. Nó là như vậy.
sbi

24

Kể từ 1.10.0 (2018-04-13), bạn có svn shelvelệnh thử nghiệm . ( TortoiseSVN hỗ trợ lệnh ) Không có gì ngoài một người trợ giúp để lưu một bản vá và áp dụng lại, do đó, nó có các giới hạn tương tự như svn diff+ patch(tức là không thể xử lý các tệp nhị phân và đổi tên). ( Chỉnh sửa : Có vẻ như hỗ trợ nhị phân sẽ đến ở phiên bản tiếp theo 1.11.0 )

Chỉnh sửa ^ 2: Với 1.11.0 (phát hành 2018-10-30), các tệp nhị phân được hỗ trợ . Kệ đổi tên tập tin vẫn không được hỗ trợ. Giá trong 1.11 không tương thích với giá được tạo bởi 1.10.

Chỉnh sửa ^ 3: Với 1.12.0 (phát hành 2019-04-24), Sao chép và đổi tên được hỗ trợ . Giá trong 1.12 không tương thích với giá được tạo bởi các phiên bản trước.

Sửa ^ 4: Không có sự thay đổi xung quanh kệ với 1.13.01.14.0 . Các lệnh vẫn được đánh dấu là thử nghiệm và bạn cần xác định SVN_EXPERIMENTAL_COMMANDS=shelf3để bật tính năng này. Có vẻ như tính năng này hiện chưa được xử lý .

Ghi chú thiết kế có thể được tìm thấy tại Wiki của nhà phát triển .

$ 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

Tôi không biết một cách dễ dàng để làm điều đó chỉ với svn. Thành thật mà nói, tôi khuyên bạn nên sử dụng git-svnđể tạo một repo git hoạt động như một bản sao làm việc svn và chỉ sử dụng git stashvới nó. Chỉ cần thay thế git pullbằng git svn rebasegit pushbằng git svn dcommitvà bạn thực sự có thể giữ 90% quy trình công việc git của mình và vẫn đang nói chuyện với một máy chủ svn.


Nhưng liên kết stackoverflow.com/questions/1554278/ Từ tôi đề cập trong các ý kiến ​​ở trên không đề xuất giải pháp thực tế để thực hiện một stash trong svn.
VonC

Đủ công bằng; thực tế, google dẫn tôi đến giải pháp đó trên một blog mới đây. Tôi vẫn duy trì rằng, đối với người hỏi này, git-svn là một giải pháp tự nhiên.
Walter Mundt

Tôi nghi ngờ rằng giải pháp theo sau đổi tên tập tin, vì git không.
NO_NAME

4

Có một tập lệnh Python 2 nhỏ được gọi là svn-stashcó sẵn theo GPL 3: https://github.com/frankcortes/svn-stash .

Nó hoạt động giống như các svn diff/patchgiải pháp được đề cập và cung cấp đẩy và xuất hiện các thay đổi khi khác với một số thư mục địa phương. Thật không may, các stash không thể được đặt tên và chỉ có thể xuất hiện cái cuối cùng (vâng, vâng, đó là một ngăn xếp, nhưng không có lý do thực sự nào cho giới hạn đó.) Nhưng sau đó, bạn luôn có thể xây dựng các tính năng bị thiếu vào nguồn.

Nó được viết cho * ix, nhưng sau khi thay thế mọi "/" bằng os.sepnó cũng hoạt động độc đáo trong Windows.

Nếu bạn sử dụng svn 1.7 trở lên, bạn cần thay đổi is_a_current_stash(): xóa dòng if ".svn" in os.listdir(CURRENT_DIR):, vì chỉ có một tiểu thư .svn cấp cao nhất trong 1.7 WC.


Nó không cho tôi dưới cửa sổ! :(
Antonio Petricca

4

Bạn có thể làm điều đó một cách dễ dàng bằng Intellij IDEA - Thay đổi giá trị


Liệu cách này có thể xử lý metadata changesdirectory creates/deletes? Giống như chính xác những gì git stashkhông?
wonsuc

3

một tùy chọn khác là sao chép thanh toán hiện tại của bạn vào một thư mục mới và hoàn nguyên tất cả các thay đổi của bạn. bằng cách này, bạn sẽ tiết kiệm được rắc rối khi tạo một nhánh tạm thời trên máy chủ của mình, sau khi tất cả các hoạt động khai thác là một hoạt động cục bộ, điều mà không phải ai cũng nên thấy và có thể được thực hiện khá thường xuyên.

sau khi xác nhận hotfix của bạn, bạn có thể cập nhật bản sao làm việc chính của mình và xóa khu vực stash của bạn


Lưu ý: Về cơ bản giống như kiểm tra một bản sao làm việc thứ hai - chỉ khi không có kiểm tra :-).
sleske

6
@sleske: có, không có lượng băng thông khổng lồ cần thiết cho việc thanh toán mới
knittl

Dù muốn hay không, đây là câu trả lời phản ánh chặt chẽ hơn hành vi "git stash". Tạo một nhánh IS tuyệt vời, nhưng liên quan nhiều hơn đến giá đỡ TFS.
Charles Roberto Canato

1

Tôi cũng đã muốn tính năng này. Tôi hiện đang sử dụng TortoiseSVN.

Tôi chưa tìm thấy giải pháp cứng nào ngoại trừ xuất cây, quay trở lại kho lưu trữ thực hiện các thay đổi và cam kết của tôi, sau đó so sánh các thay đổi từ cây xuất trở lại vào thư mục được kiểm soát nguồn của tôi bằng cách sử dụng công cụ như Beyond So sánh.

Hoặc, một giải pháp khác có thể là phân nhánh từ thư mục này sang thư mục khác, thực hiện các thay đổi của bạn và cam kết. Khi bạn đã sẵn sàng để hợp nhất những bản đó lại với bản sao làm việc khác của mình, hãy cập nhật và hợp nhất các thay đổi của bạn.


1

Tôi luôn giữ một kiểm tra thứ hai, mà tôi gọi là "trunk_clean". Bất cứ khi nào tôi cần thực hiện một thay đổi nhanh chóng, tách biệt liên quan đến những gì tôi đang làm, tôi chỉ cam kết thay vào đó.


0

Các ý tưởng phân nhánh và vá ở trên là tuyệt vời, nhưng chúng không hoạt động tốt cho tôi. Tôi sử dụng một công cụ tìm khác biệt trực quan, vì vậy việc chạy git diffkhông tạo ra các bản vá dựa trên văn bản. Hệ thống xây dựng của chúng tôi tạo ra một môi trường mới mỗi khi một nhánh được tạo, do đó việc tạo các nhánh "stash" tạm thời sẽ trở nên lộn xộn.

Thay vào đó, tôi đã viết một tập lệnh shell nhỏ sao chép một tập tin vào thư mục "shelf", thêm dấu thời gian và hoàn nguyên thay đổi. Nó không mạnh mẽ như các giải pháp ở trên, nhưng nó cũng tránh được một số cạm bẫy mà tôi gặp phải.


0

Dựa trên câu trả lời của Walter, tôi đã tạo các bí danh sau trong tệp bashrc của mình:

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'

Những bí danh này dễ sử dụng và ghi nhớ hơn nhiều.

Sử dụng:

svn.stash để stash thay đổi và svn.stash.apply để áp dụng stash.


0

Trong thực tế, tôi sử dụng git initđể tạo một kho lưu trữ Git trong trunkthư mục của kho lưu trữ Subversion của mình và sau đó tôi thêm *.gitvào các mẫu bỏ qua Suctions.

Sau khi sửa đổi một số tệp, nếu tôi muốn tiếp tục công việc của mình với dòng chính Subversion, tôi chỉ sử dụng git stashđể lưu trữ công việc của mình. Sau khi cam kết với kho Subversion, tôi sử dụng git stash popđể khôi phục các sửa đổi của mình.


2
Đây thực sự là một giải pháp tốt! Nhiều giải pháp khác sử dụng các công cụ của bên thứ 3 để giải quyết vấn đề; công cụ này sử dụng Git như một công cụ của bên thứ 3. Điều này có một số lợi thế: 1) Git rất chung chung và mạnh mẽ. 2) Nhiều người đã cài đặt Git.
Lii

Tôi tò mò làm thế nào điều này hoạt động nếu bạn cũng không thực hiện một cam kết git.
B2K

0

Sử dụng:

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

Nó sẽ tạo một nhánh từ vị trí hiện tại và sửa đổi hiện tại, và sau đó nó sẽ cam kết những thay đổi trong bản sao làm việc cho nhánh đó mà không chuyển sang nó.

sử dụng: sao chép SRC [@REV] ... DST

Mỗi SRC và DST có thể là đường dẫn bản sao (WC) hoặc URL:

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

Lưu ý rằng các thay đổi trong bản sao làm việc sẽ không được tự động hoàn nguyên ( cpchỉ là thay đổi CoPying cho một chi nhánh mới) và bạn phải hoàn nguyên chúng theo cách thủ công.

Để khôi phục các thay đổi, bạn chỉ có thể hợp nhất các thay đổi từ nhánh mới được tạo thành bản sao làm việc của bạn.

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

--ignore-ancestry được sử dụng để không cập nhật thông tin hợp nhất trong bản sao làm việc.

Sử dụng:

svn ls -v ^/trash-stash/

để xem những gì bạn có tại đường dẫn stash. Bản sửa đổi cam kết cũng được in.

Nếu bạn không cần stash nữa, chỉ cần chạy:

svn rm ^/trash-stash/my-stash

Giải pháp này tốt hơn so với sử dụng bản vá trong đó nếu những thay đổi mới trong bản sao làm việc hoặc trên nhánh hiện tại xung đột với các thay đổi trong kho, bạn có thể giải quyết xung đột bằng phương tiện svn, trong khi patchtrong một số trường hợp sẽ thất bại hoặc thậm chí áp dụng bản vá không chính xác.


-1

Vì Subversion không hỗ trợ stashtính năng hoàn hảo,
tôi chỉ làm theo cách thủ công như thế này.

Đặt DevelopmentProduction(release)dự án đến một con đường riêng biệt.

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

Bạn có thể làm việc với bất kỳ tính năng mới nào cho dự án của bạn trong lộ trình phát triển
và bạn sẽ chỉ cam kết tiến trình có ý nghĩa hoặc một cái gì đó nên được phát hành cho ổn định.

Khi bạn phải phát hành nó để sản xuất, mở dự án sản xuất, cập nhật svn và làm công cụ để phát hành (xây dựng, xuất ... vv).

Tôi biết điều này làm cho một chút rắc rối, nhưng việc phát hành tiến bộ không xảy ra thường xuyên (nó không phù hợp với tôi, nhưng tôi biết một số dự án làm) so với phát triển tiến độ, cách này phù hợp với tôi.

Tôi đang sử dụng svn cho các dự án cụ thể vì các thành viên trong nhóm dự án sử dụng nó, vì vậy tôi phải tuân theo.
Giải pháp tốt nhất là sử dụng gitcó hệ thống kiểm soát phiên bản hoàn hảo và tốt hơn svn.


Không rõ bạn đang làm gì (phiên bản nào được kiểm tra trong các thư mục bạn đề cập?), Nhưng nó trông giống như một bản sao của câu trả lời được bình chọn hàng đầu ("Kiểm tra một bản sao làm việc mới").
sleske

@sleske Xin lỗi, tôi không đọc chi tiết trường hợp của bạn. Trong trường hợp của tôi, tôi chỉ cần devprod, 2 tình huống. Để phát triển chức năng hoàn toàn mới sẽ phức tạp với svn. Tôi không chắc có phương pháp rõ ràng để giải quyết trường hợp của bạn trong thế giới svn không.
wonsuc
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.