{"thread":{"id":"19748","subject":"Merge into locally modified files?","startedAt":"2009-06-08T17:30:22Z","lastAt":"2009-06-09T00:46:20Z","messageCount":7,"participants":["skillzero@gmail.com","Johan Herland","Andreas Ericsson","Jon Smirl","Sitaram Chamarty"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"115826","messageId":"2729632a0906081030k5048cb27p6950a0decaa7396a@mail.gmail.com","threadId":"19748","inReplyTo":null,"subject":"Merge into locally modified files?","fromName":"","fromEmail":"skillzero@gmail.com","sentAt":"2009-06-08T17:30:22Z","receivedAt":"2009-06-08T17:30:22Z","isPatch":false,"sender":{"key":"skillzero@gmail.com","avatar":null},"body":"If I have some local changes to a file that I don't want to commit\n(e.g. temp debug changes like printf's) and I see somebody else has\npushed some changes to that file, how do I merge their changes to the\nfile while trying to preserve my local changes (and conflicting if\nit's not possible)?\n\nAfter a git fetch, I tried 'git checkout --merge origin/master <path\nto my locally modified file>', but that just overwrote my local\nchanges.\n\nI'm converting people from CVS to git and this is a common thing\npeople do with CVS. They have some local changes and see that the\nserver has some other changes so they do 'cvs up' and it tries to\nmerge changes from the server into the locally modified file. The\nlocal changes are often things that will never be committed. I know\ngit tries to avoid things you can't undo, but like a 'git checkout\n<file>' that can't be undone, is there a way to say \"merge what you\ncan and generate conflict markers for things you can't?\".\n\nI think what I want to do is the equivalent of rebasing for local\nmodified files rather than committed files.\n"},{"id":"115827","messageId":"200906082022.09936.johan@herland.net","threadId":"19748","inReplyTo":"2729632a0906081030k5048cb27p6950a0decaa7396a@mail.gmail.com","subject":"Re: Merge into locally modified files?","fromName":"Johan Herland","fromEmail":"johan@herland.net","sentAt":"2009-06-08T18:22:09Z","receivedAt":"2009-06-08T18:22:09Z","isPatch":false,"sender":{"key":"johan@herland.net","avatar":"https://avatars.githubusercontent.com/u/547031?v=4"},"body":"On Monday 08 June 2009, skillzero@gmail.com wrote:\n> If I have some local changes to a file that I don't want to commit\n> (e.g. temp debug changes like printf's) and I see somebody else has\n> pushed some changes to that file, how do I merge their changes to the\n> file while trying to preserve my local changes (and conflicting if\n> it's not possible)?\n>\n> After a git fetch, I tried 'git checkout --merge origin/master <path\n> to my locally modified file>', but that just overwrote my local\n> changes.\n>\n> I'm converting people from CVS to git and this is a common thing\n> people do with CVS. They have some local changes and see that the\n> server has some other changes so they do 'cvs up' and it tries to\n> merge changes from the server into the locally modified file. The\n> local changes are often things that will never be committed. I know\n> git tries to avoid things you can't undo, but like a 'git checkout\n> <file>' that can't be undone, is there a way to say \"merge what you\n> can and generate conflict markers for things you can't?\".\n>\n> I think what I want to do is the equivalent of rebasing for local\n> modified files rather than committed files.\n\nBeing a CVS convert myself, I know this may be difficult to grasp when \ncoming from CVS. Here's the deal: In the scenario you describe above, \nCVS forces you to merge your local modifications with the updates from \nthe server. Thus, if/when you commit your changes, they will no longer \nbe your changes only, but they will also contain whatever you did to \nresolve the conflicts. (This is also know as \"merge-before-commit\".)\n\nGit, instead encourages you to commit your changes _first_ \n(aka. \"commit-before-merge\"), so that your changes are not necessarily \naffected by the updated changes from the server. By committing your \nchanges first, you can choose at a later date whether to _merge_ your \nchanges into the updates from the server (in a separate merge commit), \nor whether to _rebase_ your changes on top of the updates from the \nserver (as if you made your changes after the update, and not before \nthe update).\n\nIn this scenario, since you have not published your changes, it makes \nsense to rebase them on top of the updates from the server. In other \nwords, what you should do is first \"git commit\" your changes, and \nthen \"git fetch\" and \"git rebase origin/master\". (You can also use \"git \npull --rebase\" instead of the last two commands.)\n\nNow, since you probably don't want to push your changes (debug printfs \netc.), you should probably put them on a separate branch, so that they \nare not automatically part of your next \"git push\". If you have already \ncommitted them to you local \"master\" branch, you can do the following:\n\n\tgit checkout -b debug  # Create and switch to a new branch \"debug\"\n\tgit branch -f master HEAD^ # Reset \"master\" to the previous commit\n\nYour \"master\" is now back \"in sync\" with the server, and you have a \ndebug branch which contains your debug printfs. Now, when you make \nfurther changes, you can choose whether to put them on \"master\" \nor \"debug\".  With a default push configuration, \"git push\" will now \npush \"master\", but not \"debug\", so your debug printfs will stay in your \nlocal repo. Note that if you still need the debug printfs after there \nare more commits on \"master\", you will have to\n\n\tgit checkout debug\n\tgit rebase master\n\nto put your debug printfs back on top of the \"master\" branch.\n\n\nBTW, I find it very helpful to use gitk to visualize the commit history \nbefore and after each of these commands, so that I get a \"natural\" feel \nfor how each command operates on the commit graph.\n\n\nHave fun! :)\n\n...Johan\n\n-- \nJohan Herland, <johan@herland.net>\nwww.herland.net\n"},{"id":"115830","messageId":"2729632a0906081214q43e45ce7p812bd02f34934691@mail.gmail.com","threadId":"19748","inReplyTo":"200906082022.09936.johan@herland.net","subject":"Re: Merge into locally modified files?","fromName":"","fromEmail":"skillzero@gmail.com","sentAt":"2009-06-08T19:14:38Z","receivedAt":"2009-06-08T19:14:38Z","isPatch":false,"sender":{"key":"skillzero@gmail.com","avatar":null},"body":"On Mon, Jun 8, 2009 at 11:22 AM, Johan Herland <johan@herland.net> wrote:\n>\n> Git, instead encourages you to commit your changes _first_\n> (aka. \"commit-before-merge\"), so that your changes are not necessarily\n> affected by the updated changes from the server.\n\nThe problem I have with this is that it's a lot of extra work to\ncommit, pull (which will create a merge commit), then back out the\nmerge commit git pull did, back out my local commit, then re-apply my\nlocal changes. I typically always have some modified files in my tree\nfor little things I may never want to commit. I'll tweak some build\nMakefile build setting (e.g. enable extra logging, some debug printfs,\netc.). These changes are very transient. We tend to pull in changes\nseveral times a day as people change stuff.\n\nIt looks like I can use git stash to help here. If I do 'git stash &&\ngit pull && git stash pop', it seemed to work in a simple example. If\nI had no changes, I'd need to be careful to not try to do a git stash\npop since it would haven't stashed anything.\n\nIs this something that would be pretty easy to add to git pull (or I\nguess really to git merge since pull is just fetch+merge)? Maybe\nsomething like a 'git pull --rebase-local'? If I wanted to add\nsomething like this, should I just start by looking at git stash and\nsee how it does it and try to integrate support for that into git\nmerge (and make sure git pull will pass that option through to git\nmerge)? Conceptually, it seems easy, but I don't know how hard it\nwould be to get it into the code.\n"},{"id":"115856","messageId":"200906090036.43492.johan@herland.net","threadId":"19748","inReplyTo":"2729632a0906081214q43e45ce7p812bd02f34934691@mail.gmail.com","subject":"Re: Merge into locally modified files?","fromName":"Johan Herland","fromEmail":"johan@herland.net","sentAt":"2009-06-08T22:36:43Z","receivedAt":"2009-06-08T22:36:43Z","isPatch":false,"sender":{"key":"johan@herland.net","avatar":"https://avatars.githubusercontent.com/u/547031?v=4"},"body":"On Monday 08 June 2009, skillzero@gmail.com wrote:\n> On Mon, Jun 8, 2009 at 11:22 AM, Johan Herland <johan@herland.net> wrote:\n> > Git, instead encourages you to commit your changes _first_\n> > (aka. \"commit-before-merge\"), so that your changes are not necessarily\n> > affected by the updated changes from the server.\n>\n> The problem I have with this is that it's a lot of extra work to\n> commit, pull (which will create a merge commit), then back out the\n> merge commit git pull did, back out my local commit, then re-apply my\n> local changes.\n\nI never suggested you do something convoluted like that. What I suggested \nwas:\n\n1. \"git commit\" your local changes\n2. \"git pull --rebase\"\n\nAfter this, your local changes will be on top of the pulled changes. (Then \nyou can put them on a separate branch, if you're paranoid about accidentally \npushing them to the server.)\n\n> I typically always have some modified files in my tree\n> for little things I may never want to commit. I'll tweak some build\n> Makefile build setting (e.g. enable extra logging, some debug printfs,\n> etc.). These changes are very transient. We tend to pull in changes\n> several times a day as people change stuff.\n\nYes, and that's why I suggest you keep your debug stuff on a separate \nbranch, so that it's easily separated from the mainline development.\n\n> It looks like I can use git stash to help here. If I do 'git stash &&\n> git pull && git stash pop', it seemed to work in a simple example.\n\nYes, that's another way of doing it; possibly better than my suggestion.\n\n> If I had no changes, I'd need to be careful to not try to do a git stash\n> pop since it would haven't stashed anything.\n\nIf this is the only thing you use 'git stash' for, you could start off with \na 'git stash clear'. That way, there would be nothing to 'pop' if there was \nnothing to 'stash'.\n\n> Is this something that would be pretty easy to add to git pull (or I\n> guess really to git merge since pull is just fetch+merge)? Maybe\n> something like a 'git pull --rebase-local'? If I wanted to add\n> something like this, should I just start by looking at git stash and\n> see how it does it and try to integrate support for that into git\n> merge (and make sure git pull will pass that option through to git\n> merge)? Conceptually, it seems easy, but I don't know how hard it\n> would be to get it into the code.\n\nFeel free to whip up a patch. I can't say whether it'll be accepted or not.\n\n\nHave fun! :)\n\n...Johan\n\n-- \nJohan Herland, <johan@herland.net>\nwww.herland.net\n"},{"id":"115860","messageId":"4A2D9A4A.60804@op5.com","threadId":"19748","inReplyTo":"2729632a0906081030k5048cb27p6950a0decaa7396a@mail.gmail.com","subject":"Re: Merge into locally modified files?","fromName":"Andreas Ericsson","fromEmail":"exon@op5.com","sentAt":"2009-06-08T23:10:02Z","receivedAt":"2009-06-08T23:10:02Z","isPatch":false,"sender":{"key":"exon@op5.com","avatar":null},"body":"skillzero@gmail.com wrote:\n> If I have some local changes to a file that I don't want to commit\n> (e.g. temp debug changes like printf's) and I see somebody else has\n> pushed some changes to that file, how do I merge their changes to the\n> file while trying to preserve my local changes (and conflicting if\n> it's not possible)?\n> \n> After a git fetch, I tried 'git checkout --merge origin/master <path\n> to my locally modified file>', but that just overwrote my local\n> changes.\n> \n> I'm converting people from CVS to git and this is a common thing\n> people do with CVS. They have some local changes and see that the\n> server has some other changes so they do 'cvs up' and it tries to\n> merge changes from the server into the locally modified file. The\n> local changes are often things that will never be committed. I know\n> git tries to avoid things you can't undo, but like a 'git checkout\n> <file>' that can't be undone, is there a way to say \"merge what you\n> can and generate conflict markers for things you can't?\".\n> \n> I think what I want to do is the equivalent of rebasing for local\n> modified files rather than committed files.\n\n\ngit stash && git pull && git stash pop\n\nshould do roughly what you want.\n\n/Andreas\n"},{"id":"115861","messageId":"9e4733910906081619u19f12220g7fab11c94b9aa8a5@mail.gmail.com","threadId":"19748","inReplyTo":"2729632a0906081030k5048cb27p6950a0decaa7396a@mail.gmail.com","subject":"Re: Merge into locally modified files?","fromName":"Jon Smirl","fromEmail":"jonsmirl@gmail.com","sentAt":"2009-06-08T23:19:37Z","receivedAt":"2009-06-08T23:19:37Z","isPatch":false,"sender":{"key":"jonsmirl@gmail.com","avatar":"https://gravatar.com/avatar/cff3bf5bfdfa6708b905712ff91f0f9b8aaca161659f38c02b787920d5d28b7e?d=mp&s=160"},"body":"On Mon, Jun 8, 2009 at 1:30 PM, <skillzero@gmail.com> wrote:\n> If I have some local changes to a file that I don't want to commit\n> (e.g. temp debug changes like printf's) and I see somebody else has\n> pushed some changes to that file, how do I merge their changes to the\n> file while trying to preserve my local changes (and conflicting if\n> it's not possible)?\n>\n> After a git fetch, I tried 'git checkout --merge origin/master <path\n> to my locally modified file>', but that just overwrote my local\n> changes.\n\nI use stgit to do this all of the time. stgit is all about patch\nstacks. You just add your debug stuff to a stgit patch and then you\ncan push/pop it.\n\nstg new debug-patch\n..make debug edits..\nstg refresh\n\ngit fetch origin\nstg rebase origin/master\n... fix conflicts, you get prompted...\n\nyou're done.\n\n\n>\n> I'm converting people from CVS to git and this is a common thing\n> people do with CVS. They have some local changes and see that the\n> server has some other changes so they do 'cvs up' and it tries to\n> merge changes from the server into the locally modified file. The\n> local changes are often things that will never be committed. I know\n> git tries to avoid things you can't undo, but like a 'git checkout\n> <file>' that can't be undone, is there a way to say \"merge what you\n> can and generate conflict markers for things you can't?\".\n>\n> I think what I want to do is the equivalent of rebasing for local\n> modified files rather than committed files.\n> --\n> To unsubscribe from this list: send the line \"unsubscribe git\" in\n> the body of a message to majordomo@vger.kernel.org\n> More majordomo info at  http://vger.kernel.org/majordomo-info.html\n>\n\n\n\n-- \nJon Smirl\njonsmirl@gmail.com\n"},{"id":"115867","messageId":"slrnh2rc6s.s8o.sitaramc@sitaramc.homelinux.net","threadId":"19748","inReplyTo":"2729632a0906081214q43e45ce7p812bd02f34934691@mail.gmail.com","subject":"Re: Merge into locally modified files?","fromName":"Sitaram Chamarty","fromEmail":"sitaramc@gmail.com","sentAt":"2009-06-09T00:46:20Z","receivedAt":"2009-06-09T00:46:20Z","isPatch":false,"sender":{"key":"sitaramc@gmail.com","avatar":"https://avatars.githubusercontent.com/u/43316?v=4"},"body":"On 2009-06-08 19:14:38, skillzero@gmail.com <skillzero@gmail.com> wrote:\n\n> Is this something that would be pretty easy to add to git pull (or I\n> guess really to git merge since pull is just fetch+merge)? Maybe\n> something like a 'git pull --rebase-local'? If I wanted to add\n\nI'd just use an alias.  Either a bash alias like\n    alias cvsup='git stash && git pull && git stash pop'\nor a git alias like\n    git config --global alias.cvsup '!git stash && git pull && git stash pop'\n\nThe latter is probably better aesthetically, and you'd call\nit by saying \"git cvsup\".\n\nFar cleaner than patching git-pull, no?\n"}]}