From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: Stefan Monnier Newsgroups: gmane.emacs.devel Subject: Splitting changes (was: support for bzr shelve/unshelve in vc-dir) Date: Thu, 03 Dec 2009 12:05:49 -0500 Message-ID: References: <200912011947.nB1JlaAp027561@godzilla.ics.uci.edu> <200912030748.nB37m5V4022253@godzilla.ics.uci.edu> <87k4x431n2.fsf@telefonica.net> <200912030907.nB39781X022853@godzilla.ics.uci.edu> NNTP-Posting-Host: lo.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-Trace: ger.gmane.org 1259862243 17329 80.91.229.12 (3 Dec 2009 17:44:03 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Thu, 3 Dec 2009 17:44:03 +0000 (UTC) Cc: =?iso-8859-1?Q?=D3scar?= Fuentes , emacs-devel@gnu.org To: Dan Nicolaescu Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Thu Dec 03 18:43:55 2009 Return-path: Envelope-to: ged-emacs-devel@m.gmane.org Original-Received: from lists.gnu.org ([199.232.76.165]) by lo.gmane.org with esmtp (Exim 4.50) id 1NGFfL-0002KZ-Jh for ged-emacs-devel@m.gmane.org; Thu, 03 Dec 2009 18:40:31 +0100 Original-Received: from localhost ([127.0.0.1]:59301 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1NGFfL-0005tp-BJ for ged-emacs-devel@m.gmane.org; Thu, 03 Dec 2009 12:40:31 -0500 Original-Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1NGF8D-0006CV-13 for emacs-devel@gnu.org; Thu, 03 Dec 2009 12:06:17 -0500 Original-Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1NGF88-0006AH-AK for emacs-devel@gnu.org; Thu, 03 Dec 2009 12:06:16 -0500 Original-Received: from [199.232.76.173] (port=43531 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1NGF88-0006A9-5k for emacs-devel@gnu.org; Thu, 03 Dec 2009 12:06:12 -0500 Original-Received: from chene.dit.umontreal.ca ([132.204.246.20]:57432) by monty-python.gnu.org with esmtp (Exim 4.60) (envelope-from ) id 1NGF87-00030X-ER for emacs-devel@gnu.org; Thu, 03 Dec 2009 12:06:11 -0500 Original-Received: from faina.iro.umontreal.ca (faina.iro.umontreal.ca [132.204.26.177]) by chene.dit.umontreal.ca (8.14.1/8.14.1) with ESMTP id nB3H5nNb032728; Thu, 3 Dec 2009 12:05:49 -0500 Original-Received: by faina.iro.umontreal.ca (Postfix, from userid 20848) id 8B5633A14D; Thu, 3 Dec 2009 12:05:49 -0500 (EST) In-Reply-To: <200912030907.nB39781X022853@godzilla.ics.uci.edu> (Dan Nicolaescu's message of "Thu, 3 Dec 2009 01:07:08 -0800 (PST)") User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/23.1.50 (gnu/linux) X-NAI-Spam-Score: 0 X-NAI-Spam-Rules: 1 Rules triggered RV3420=0 X-detected-operating-system: by monty-python.gnu.org: GNU/Linux 2.6 (newer, 3) X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Original-Sender: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Xref: news.gmane.org gmane.emacs.devel:118186 Archived-At: >> The implementation shelves all the changes on the current >> branch. Although this is useful, an usual application of `shelve' is for >> temporarily removing out of your way some changes (allowing to commit >> only specific changes of the edited files, for example.) An ideal >> implementation of `shelve' for vc would show the output of `bzr diff', >> mark the hunks you want to shelve, and then run the command. Sadly, it >> seems impossible to non-interactively indicate to bzr which hunks it >> should shelve. > That's exactly the reason for the current implementation. > Patches to add other methods to create shelves (including an > interactive) are surely welcome. I've been interested in this issue for a while now: I've been using a local patch to VC which adds a command "vc-prepare-for-partial-commit", which allows to choose which part of some local changes should be committed and which part should be kept for later. I've never installed it in the trunk for various reasons, but I've use it extensively for many years. In this time I noticed the following: - selecting only by files is not a fine enough granularity. - selecting only by hunks is sometimes sufficient, but even that is too coarse in my experience. The typical problem is that I want to split a change into a cleanup part and an actual new feature, but in most cases all the cleanup changes touch the exact same code as the new feature, so many of the hunks mix both. So the way my hack works is the following: - it takes ("stashes") a copy of the current state. - then it lets you make any changes you want (the intention is that you're going to revert the changes you want to keep for later). You can do this part at any granularity: files, hunks, or even by hand. - when done, you commit, after which the saved files are re-instated. This gives me great flexibility, and lets me use any tool I want to select which parts to keep and which parts not. So I really like it. But it has some serious drawbacks: - if the final commit fails because the tree is not uptodate (any more), the backend won't know that the update should apply to both the file and its "stashed" copy. So you end up having to deal with updates missing from the stashed copy, or abort the partial commit (i.e. revert to the stashed copy), then update, then re-do the split by hand. - when doing the split by hand, you can make any change you want. The intention is for those changes to "undo" part of the local changes, but nothing prevents you from adding new changes during this time (as you revisit the code to choose how to split your changes, you may bump into new opportunities for cleanup and it's sometimes difficult to refrain from doing them at that point). And if you do add local changes, then these will be undone after commit when the saved files are re-instated. So I'd like VC to support something like that, but in a way that is a bit more robust. The way I see it working ideally is something like the following: - the copy is taken by committing the local changes on a new temporary branch (IIUC, that's pretty much what "git stash" does). - then revert to the original branch and reapply those same changes (without committing them). - at this point the user can use any tool he likes to remove parts of those changes he doesn't want to commit yet. She can also "update" her tree when needed. - when she's ready, she can perform the "commit", after which VC will ask to merge the temporary branch (without committing the result), which will hopefully result in pretty much the same as the original code before this whle partial commit took place. The advantage here, is that because we use branches rather than manually copying files behind the VCS's back, the VCS has all the needed meta-data to ensure that no change is accidentally lost or undone. The disadvantage is that the final merge is likely to introduce spurious conflicts since it will re-apply the parts of the changes that were just committed. But if "same change conflicts" are automatically resolved by your merge tool, then all the changes that were selected at the granularity of a hunk (or larger) should be merged without conflict. I.e. you should only see conflicts when you actually take advantage of the extra flexibility. Stefan