Skip navigation

Category Archives: Version Control

This weekend, I made an interesting (re)discovery. I was digging though some old emails and found an email with details about how an acquaintance and I were creating a centralized git workflow.

I figured out how to keep my project in sync with yours.
I use git on the command-line, but I imagine it should translate to a GUI tool pretty easily

git add remote upstream
git fetch upstream
git stash //I had uncommitted changes that I had to get off the stack first
git rebase upstream/master
git stash apply //to reapply my changes, I had to manual merge a few issues.

Anyway, thought I’d share with you in case you get other contributors to your IDE.

Later,

Ben

This was highly relevant for me personally, as we have been discussing the benefits of SVN vs Git at work lately. SVN’s centralized structure is simple enough to understand that everyone groks it from the jump. But keeping Git in sync, with its distributed workflows, is a much more convoluted process for new users.

With the above setup to a git instance, it allows a user to maintain local changes, while still being able to keep up-to-date with the latest pushed changes. Being able to rebase, based on the most recent changes to the upstream repo (aka, the centralized shared home of the project) makes keeping everyone in a centralized git workflow so much easier.

If you add ‘–‘ to your git command, git will know not to process anything after the double hyphen as a command-line argument.
This was useful to know for the situation I just found myself in. I had accidentally cloned a repo into a directory called “–force”. I had placed the –force argument in the wrong sequence in the clone command. But when I went to remove it from git, I found I could not. Every ‘git rm --force‘ command was throwing up the usage guide for the rm command; git thought I was passing in ‘–force’ as an argument. I found out about using the ‘–‘ argument with git and ‘git rm -- --force‘ got rid of my bad directory.

My first open source contribution was just accepted! (Technically, it’s my 2nd contribution, but 1st accepted one!) It was a very minor change, just an update to the user’s profile page on GitLab. Nevertheless, it’s a great feeling, knowing that I can directly improve a great product that I actually use. And I gained a bit of git experience because of this as well.

simple git history

So pretty!

Before I get to what I broke and how I fixed it, I feel the need to defend my self a little first. I like seeing the pretty, flowy lines that are used to track the commits of a project in git. However, the entirety of my git experience has been as a solo developer. As such, I have noticed that every time I merged my feature branch into master, there was no fork reflected in the history (using git log --oneline --decorate --graph). Just a boring-ass straight line. So, purely for aesthetics and not at all efficient or appropriate, I found a way I could get this fork & branch history to show in my logs. I performed my merges with no fast-forwards (git merge --no-ff). This creates an additional commit that mentions the two branches that are merged together, but achieved the effect I was looking for.

So fast-forward (HA!) to today. I followed my usual, ignorant workflow for my submission to the Gitlab project. I forked their repo, cloned locally, branched, made changes, merged with no-ff back to master, and pushed back to origin. From here, I made a merge request for my change to the official GitLab Community Edition project. An admin wrote back that I needed to squash my two commit messages into one. Blerg, I should have known that this practice would eventually bite me! I spent the next few hours unsuccessfully trying to figure this out on my own. After responding to the admin the next day, that I was still working on this, he wrote back with a very helpful link.
So, to squash my pointless commit that --no-ff generated, I had to rebase back to the commit before my first commit. I did this, in interactive mode (git rebase -i <hash of commit>). This opens a text editor with the history of commits between the latest commit and the one that was selected for rebase. In my case, saw my commit, and the autogenerated commit. From the text editor that appears, I can then select what happens with each commit.

# Rebase 408a140..5d5af41 onto 408a140
#
# Commands:
# p, pick = use commit
# r, reword = use commit, but edit the commit message
# e, edit = use commit, but stop for amending
# s, squash = use commit, but meld into previous commit
# f, fixup = like "squash", but discard this commit's log message
# x, exec = run command (the rest of the line) using shell
#
# These lines can be re-ordered; they are executed from top to bottom.
#
# If you remove a line here THAT COMMIT WILL BE LOST.
#
# However, if you remove everything, the rebase will be aborted.
#
# Note that empty commits are commented out

My case was simple. I chose fixup for the superfluous commit and pick for my commit. After saving these changes, the rebase occurred. Everything is fine now, right?
Nope, my dumbass pushed the change to the remote repo already, so I had to overwrite that master branch with my new master branch. A normal git push wouldn’t do it because my local and remote repos were out of sync. Some kind of fast-forward error. So I just forced my changes to overwrite my remote master branch.

git push --force

Ha ha ha Force Push!

git push --force origin master

This force push added my revised master branch to my remote and let me successfully merge my change into the GitLab source! Awesome! Proof positive that you don’t have to be some sort of programming genius to be able to contribute. I don’t even know Ruby!

I am not sure how long Github has offered their Pages service, but I only recently discovered it. And, as I have been trying to improve my workflow, I found the idea of deploying my site with a simple “git push” very enticing.
I experimented briefly with Pages and decided to go with Github for my webpage hosting. However, I quickly realized I had a problem. I had an existing Github repo that housed the code for bencarson.net. I also had a Github repo in ben-carson.github.io that I had created for my Pages experimentation. I didn’t want to lose the history of my original website project. And I also didn’t really want to just copy-and-paste my original site’s files over my Pages repo, that just felt too inelegant. What I really wanted was to combine these two distinct git projects and their histories into one project.
My Git-fu is still pretty weak, so I took to the web for help. My initial searches provided results on merging subtrees and modules and whatnot. More along the lines of keeping a library that a project uses up-to-date, rather than a one-time project meld. Way overkill for my needs. Then I found this post. It was close to exactly what I was looking for.
For the sake of clarity, I’ll include just the (DOS) commands I ran for this process:

C:\> mkdir bencarson-website

C:\> cd bencarson-website

C:\bencarson-website> git init
Initialized empty Git repository in c:/dev/workspace/blog-post/.git/

C:\bencarson-website> dir > deleteme.txt

C:\bencarson-website> git add .

C:\bencarson-website> git commit -m “Initial commit”

C:\bencarson-website> git remote add bc-gh-io-remote https://ben-carson@github.com/ben-carson/ben-carson.github.io.git

C:\bencarson-website> get fetch bc-gh-io-remote
warning: no common commits
remote: Counting objects: 73, done.
remote: Compressing objects: 100% (55/55), done.
remote: Total 73 (delta 11), reused 69 (delta 10)
Unpacking objects: 100% (73/73), done.
From https://github.com/ben-carson/ben-carson.github.io
* [new branch] master -> bc-gh-io-remote/master

C:\bencarson-website> git merge bc-gh-io-remote/master

C:\bencarson-website> git rm deleteme.txt
rm ‘deleteme.txt’

C:\bencarson-website> git commit -m “removing garbage file”
[master 05b4839] removing garbage file
1 file changed, 10 deletions(-)
delete mode 100644 deleteme.txt

#combine the ‘remote add’ and ‘fetch’ commands with the ‘-f’ parameter
C:\bencarson-website> git remote add -f bc-net-remote https://ben-carson@github.com/ben-carson/bencarson.net.git
Updating bc-net-remote
From https://github.com/ben-carson/bencarson.net
* [new branch] master -> bc-net-remote/master

C:\bencarson-website> git merge bc-net-remote/master

C:\bencarson-website> git remote remove bc-net-remote

C:\bencarson-website> git remote rename bc-gh-io-remote origin

C:\bencarson-website> git push origin master

After this, my new, history-merged, site was pushed up to ben-carson.github.io and is available[Edit 03.10.15: removed all my github stuff]! Super easy, once you know how to do it.

%d bloggers like this: