GIT Filter Branch
Ever committed a folder that shouldn't be a GIT? e.g.
For my case with Jekyll, I committed
_posts folder, which really should be put as
git submodule instead.
This is my journey in fixing them.
Basically there are two basic concepts in this:
_postsfolder out of the current repository
- Add a git submodule under
git filter-branch --subdirectory-filter _posts
This deletes all files, except for the filtered directory, while preserving the history of it. In most cases it should be enough for step 1.
Unfortunately for me the above command doesn't really get what I want which is a clean history containing only my posts commits.
This is because Minimal Mistake's historically committed posts into
_posts folder, thus the history is kind of noisy.
git filter-branch --tree-filter 'rm -rf _posts' --prune-empty HEAD
||rewrite the tree and its content. Note that
||used in conjuction with
||removes empty commits which may be created. Though, I think this is quite negligible on my case|
||this is the
However this changes all of the commits id, which pretty much means it would be hard to converse with branches which has the same history as the old branch. In this case, I might want to implement future Minimal Mistake's commit, thus I don't take this approach
git rm and git submodule add
Thus my only option left is by doing an old fashion
1. Extract the
_posts data out
cd <my_jekyll_directory> cp _posts/* <backup_directory>
2. Create an empty repository in git
For example: https://github.com/djoepramono/jekyll-posts and fill the repository with the content of the backup directory.
Why? Because in recent git,
git add submodule would automatically checkout master branch as well
cd <backup_directory> git init git remote add origin https://github.com/djoepramono/jekyll-posts git push origin master
3. Clean up
cd <my_jekyll_directory> git rm _posts/* # Delete posts that is already committed to GIT rm _posts/* # Delete posts that is not yet committed to GIT
4. Add git submodule
# Add git submodule which has to be a public repo with https git submodule add https://github.com/djoepramono/jekyll-posts _posts # commit the automatically staged files for the git submodules # i.e. .gitmodules and _posts git commit -m 'add submodule'
.gitmodules when success.
5. [OPTIONAL] Surpress gitsubmodule status
Change the newly created
.gitsubmodules as follows
[submodule "_posts"] path = _posts url = https://github.com/djoepramono/jekyll-posts ignore = dirty
Why? Because otherwise when you do
git status there will always be something like
$ git status On branch master Your branch is up-to-date with 'origin/master'. Changes not staged for commit: (use "git add <file>..." to update what will be committed) (use "git checkout -- <file>..." to discard changes in working directory) (commit or discard the untracked or modified content in submodules) modified: _posts (untracked content)
6. Last but not least, copy the _posts content back
cp <backup_directory>/* _posts
And voila! It should work, even Sublime Jekyll Plugin is still functioning normally