views:

1280

answers:

7

I use Tortoise SVN usuallly, but I have been looking into Mercurial since it is a distributed revision control system.

What I am looking for, in both systems, is a tool that let me pick only parts of a file and commit them. If I want to do this now, I have to copy to a temp version of the file and keep only the changes I want to commit in the current version, and then copy the temp version to the current version again after committing. It's just such a hassle and the program should be able to do this for me.

I heard Git supports this, please let me know if this is correct.

A: 

I have used all of the tools you mention and have never come across a way to commit only a part of a file. If you often have changes that you may not want to commit, you should read up on how branching and merging works.

Ben Hoffstein
A: 

I've never heard of such for Subversion or its predecessor CVS. Presumably you want this because you're doing at least two different projects involving the same file; in that case, if you've got the resources, a better approach would probably be to have a separate working directory for each project rather than manually keeping changes separate within a file.

I don't know if Git supports what you want, but the whole process sounds tricky and error-prone to me.

David Thornley
Git supports it via an interactive mode that allows you to pick out adjacent sets of changed lines and add them to the commit. It's not something to use frequently, but it can be very handy at times.
davetron5000
+10  A: 

Mercurial can do this with the record extension.

It'll prompt you for each file and each diff hunk. For example:

% hg record
diff --git a/prelim.tex b/prelim.tex
2 hunks, 4 lines changed
examine changes to 'prelim.tex'? [Ynsfdaq?]  
@@ -12,7 +12,7 @@
 \setmonofont[Scale=0.88]{Consolas}
 % missing from xunicode.sty
 \DeclareUTFcomposite[\UTFencname]{x00ED}{\'}{\i}
-\else
+\else foo
 \usepackage[pdftex]{graphicx}
 \fi

record this change to 'prelim.tex'? [Ynsfdaq?]  
@@ -1281,3 +1281,5 @@
 %% Local variables:
 %% mode: latex
 %% End:
+
+foo
\ No newline at end of file
record this change to 'prelim.tex'? [Ynsfdaq?]  n
Waiting for Emacs...

After the commit, the remaining diff will be left behind:

% hg di
diff --git a/prelim.tex b/prelim.tex
--- a/prelim.tex
+++ b/prelim.tex
@@ -1281,3 +1281,5 @@
 %% Local variables:
 %% mode: latex
 %% End:
+
+foo
\ No newline at end of file

Alternatively, you may find it easier to use MQ (Mercurial Queues) to separate the individual changes in your repository into patches. There is a MQ variant of record (qrecord), too.

Update: Also try the crecord extension, which provides a curses interface to hunk/line selection.

Nicholas Riley
Shame there isn't a GUI tool for this. It's wonderful to do this with GitX.
Max Howell
Amen. GitX is *the* reason I use Git; wish Murky was as capable. (Unfortunately I'm too overloaded with open source projects to fix it, though I have contributed to both GitX and Murky :-)
Nicholas Riley
There is a GUI tool for this: Tortoisehg supports hunk selection.
Hauge
I meant a Mac GUI.
Nicholas Riley
…and having now used TortoiseHg, it lacks the ability to revert a hunk, which GitX provides, and in general provides a much less useful interface. The ability to easily remove unintended (e.g. whitespace-only) changes from a diff is pretty much essential...
Nicholas Riley
+3  A: 

I would recommend not working like this.

If you have to sets of changes, set A which is ready to check in and set B which is not ready yet, how can you be sure that only checking in set A will not break your build/tests? You may miss some lines, forget about lines in a different file, or not realize a dependency that A has on B breaking the build for others.

Your commits should be discreet atomic changes that don't break the build for you or others on you team. If you are partially committing a file you are greatly increasing the chances you will break the build for others without knowing about it until you've got some unhappy coworker knocking on your door.

The big question is, why do you feel the need to work this way?

craigb
Git allows this by grouping adjacent lines together. It can be REALLY handy if you need to check in something simple and don't want to make a branch.
davetron5000
Usually, it is because I write too much code before committing. I might change two different things in a file and want to commit them with different comments.
RobbieGee
Git supports (with git stash --keep-index) isolating only the changes that you are about to commit, which lets you run unit tests or whatever on them easily.
Greg Hewgill
Sound advise for code monkeys, but us smarter types can cope with splicing a diff up and committing it in chunks.
Max Howell
From VisionMap development conventions: "There’s no worse reviewer’s nightmare than a combination of one dangerous change with a thousand trivial ones. In this sense, a meaningful change must be thoroughly purified of any obscuring litter"
Pavel Radzivilovsky
See Ryan Tomayko's (creator of GitHub) post about it: http://tomayko.com/writings/the-thing-about-git
Yawar
+4  A: 

I asked a similar question just a little while ago, and the resulting answer of using the hgshelve plugin was exactly what I was looking for.

Before you do a commit, you can put changes from different files (or hunks of changes within a file) on the "shelf" and then commit the things you want. Then you can unshelve the changes you didn't commit and continue working.

I've been using it the past few days and like it a lot. Very easy to visualize and use.

Ted Naleid
+4  A: 

Yes, git allows you to do this. The git add command has a -p (or --patch) option that allows you to review your changes hunk-by-hunk, select which to stage (you can also refine the hunks or, edit the patches in place). You can also use the interactive mode to git-add (git add -i) and use the "p" option.

Here's a screencast on interactive adding which also demonstrates the patch feature of git add.

Pat Notz
+1  A: 

Check out TortoiseHG, which will do hunk selection and let you commit different changes to one file as to different commits.

It will even let you commit all changes to some files together with partial changes to other files in one commit.

http://tortoisehg.bitbucket.org/

Regards Jesper Hauge

Hauge