0

I am in an environment where I am supposed to only push working and consolidated commits that solve an issue. For example: "This commit fixes bug XY", "This commit adds feature YZ". (to avoid cluttering up the commit history)

What workflow should I adopt if I want to keep my local changes (debug statements, work in progress), but often (several times per day) I am asked to git pull to apply changes from the team?

I guess the idea of git is that you commit often, but an ideal situation for me would be if I could track my work in progress privately and only publish "consolidated" commits to the remote repository. And at the same time constantly be able to merge-in what my team members have done already.

"Subversion way"

I have a long history with subversion (So the main issue here might be I am thinking about this wrong), where any remote changes would be automatically merged with my local, uncommitted changes. Conflicts would be solved on checkout.

So far, in git I have been doing:

git stash 
git pull 
git stash pop

"The git way" (Commit often, merge often I guess?)

How people approach this in git in general?

I was thinking about keeping private "feature" branches and then do local squashed merges of the feature branches to master once something is finished and ready to be published, so that what gets sent into the remote repository is a single commit saying "this fixes issue XY?"

I have not tried this so far, but it looks as if I would have to do a lot of merges all the time so it does not feel right.

yak
  • 1

2 Answers2

0

I have been in a similar situation and made heavy use of git merge --squash.

I would maintain a branch with whatever commits I wanted on it as I figured out the issue then just squash it in the end as one commit with reference to the bug/defect or the like it solves.

Another option if you end up solving multiple items in a single branch, therefore want to have more than one commit but still only "to the point" commits is to do an interactive rebase within the branch, git rebase -i.

This allows you to selectively squash together commits in sequence into single commit messages, but you don't essentially have to narrow it down to just 1 final commit.

This can be painful if you're doing a lot of merges, but if you are following something like the popular git flow model you are likely making a large number of short lived branches for each item you work on anyway.

dillius
  • 506
  • 4
  • 12
0

The solution you need is (getting used to) feature branches. You should also use a master branch where you would fetch the other developers changes without affecting your work in progress (so you don't have to do that ugly git stash / git stash pop).

Then you would integrate the master branch into your feature branches using merge or rebase.

An example. You have 2 feature branches, a simple one that is ready and another one that needs more testing and in which you are currently working. You are required to publish your simple feature. For that you'll need to first fetch the other people changes that have been published in the last week (last time you updated).

For that, you first checkout the master branch:

(feature2) $ git add -A
(feature2) $ git commit -m "preemtive commit" # you can also to a stash save
(feature2) $ git checkout master
(master) $ git fetch --all mirror # get changes from the 'mirror' remote
# check the changes
(master) $ git merge mirror/master # integrate other people changes into master branch
(master) $ git checkout feat1 # the simple feature to be published
(feat1) $ git merge master # merge the changes into the feat1 branch
# do the necessary tests, check everything is OK
(feat1) $ git push mirror feat1
(feat1) $ git update-ref refs/heads/master HEAD # this i will explain later

That's it. Now you can go back to your feature2 branch. You don't need to integrate your feat1 and master there, but you can of course do it.

The last step could also be done like that:

(feat1) $ git checkout master
(master) $ git merge --ff-only feat1

This is to indicate that feat1 has been fully integrated into the master branch, the public branch.

carnicer
  • 494
  • 3
  • 9