A few months ago I created a simple template of a Puppet forge module to make clones of when starting a new module due to puppet module generate ...
leaving much to be manually edited/created. This is very handy when starting from scratch but makes a mess of the commit history if just merging it into an existing puppet module repo. It turns out that git does have the ability to squash all commits from a branch during a merge.
Start by adding git@github.com:jhoblitt/puppet-module_skel.git
as a remote for an existing repo.
$ git clone ssh://git@bitbucket.org/.../puppet-yum_base.git Cloning into 'puppet-yum_base'... remote: Counting objects: 4, done. remote: Compressing objects: 100% (2/2), done. remote: Total 4 (delta 0), reused 0 (delta 0) Receiving objects: 100% (4/4), done. $ cd puppet-yum_base $ git remote add skel git@github.com:jhoblitt/puppet-module_skel.git $ git fetch skel warning: no common commits remote: Counting objects: 13, done. remote: Compressing objects: 100% (10/10), done. remote: Total 13 (delta 0), reused 13 (delta 0) Unpacking objects: 100% (13/13), done. From github.com:jhoblitt/puppet-module_skel * [new branch] master -> skel/master $ git branch -a * master remotes/origin/HEAD -> origin/master remotes/origin/master remotes/skel/master
Now we want to merge everything from remotes/skel/master
into master with git merge but squash all the commits in remotes/skel/master
while discarding anything merge changes that has a conflict in master.
Note that git merge --squash --commit -m"msg"
will not cause a commit. It seems that with the --squash
flag you must make a manual commit.
$ git merge --squash -s recursive -X ours remotes/skel/master Squash commit -- not updating HEAD Automatic merge went well; stopped before committing as requested $ git status . # On branch master # Changes to be committed: # (use "git reset HEAD..." to unstage) # # new file: .fixtures.yml # new file: .gitignore # new file: Gemfile # new file: LICENSE # new file: Modulefile # new file: README.md # new file: Rakefile # new file: spec/spec_helper.rb # $ git commit -m"Merge puppet-module_skel" [master 8ba5245] Merge puppet-module_skel 8 files changed, 71 insertions(+) create mode 100644 .fixtures.yml create mode 100644 .gitignore create mode 100644 Gemfile create mode 100644 LICENSE create mode 100644 Modulefile create mode 100644 README.md create mode 100644 Rakefile create mode 100644 spec/spec_helper.rb
And we have a nice clean looking history that isn’t polluted with commit ids from the template repo.
$ git --no-pager log commit 8ba5245a30775181ceb611a27fd79e3ad4a8d82c Author: Joshua HoblittDate: Mon Jun 3 11:48:26 2013 -0700 Merge puppet-module_skel commit 1a7c4ce1187c0ae35d249fc460b92af19d410e0b Author: Joshua Hoblitt Date: Mon Jun 3 11:08:51 2013 -0700 first commit
Easy cut’n’paste version of the git commands:
git remote add skel git@github.com:jhoblitt/puppet-module_skel.git git fetch skel git merge --squash -s recursive -X ours remotes/skel/master git commit -m"Merge puppet-module_skel"
2014-04-11 at 12:13
Thanks a bunch for this nice, concise article! I was messing around with merge, rebase and squash for hours and still wasn’t able to figure out how to realise that specific workflow I intended to achieve. You saved my day! (and probably my weekend, as well) 😉