Skip to content

Instantly share code, notes, and snippets.

@mysterycommand
Created September 8, 2018 19:16
Show Gist options
  • Save mysterycommand/e86841357962ed72871706983e04d05f to your computer and use it in GitHub Desktop.
Save mysterycommand/e86841357962ed72871706983e04d05f to your computer and use it in GitHub Desktop.
Common Git Workflow

From scratch

Setting up

I'll assume we're starting from nothing, so the first thing we'll need to do is clone the repo … but where to put it? I like to organize files on my local machine in a way that's similar to how GitHub does it. Locally I'll put everything in a "Sites" folder in my home directory. The short hand way of refering to this in Terminal is ~/Sites/ (~/ is an alias for /Users/<your user name>/), so the full path to your sites folder is /Users/<your user name>/Sites/.

To keep with the theme of "local machine organized like GitHub", we'll start by making a directory for the organization or owner of the repo we're going to clone. This is the first part of a GitHub URL which have the form of https://github.com/<organization or owner>/<repo name>, so:

# mkdir is short for "make directory"
$ mkdir ~/Sites/<organization or owner>
# cd is short for "change directory" (chdir was already taken I guess)
$ cd ~/Sites/<organization or owner>

Now you'll be "in" the <organization or owner> directory at ~/Sites/<organization or owner>. This sets up the basic folder structure we'll follow:

For any repo on GitHub, the URL https://github.com/<organization or owner>/<repo name> will be on my local machine as ~/Sites/<organization or owner>/<repo name>.

Cloning a repo

At this point we have a directory at ~/Sites/<organization or owner> and we're going to clone a repo into a new directory <repo name> (so the full path will be ~/Sites/<organization or owner>/<repo name> or /Users/<your user name>/Sites/<organization or owner>/<repo name> as described above). We're almost ready to clone the repo, but there's one more thing to mention.


HTTPS or SSH

When cloning a repo GitHub gives you a green "Clone or download" button, shows a small dropdown when clicked showing you the URL you'll use to do the cloning with a heading of either Clone with SSH or Clone with HTTPS (there's also a link to "Use ") that basically toggles between the two forms.

The difference is described really well in GitHub docs, but basically it's how you'll verify that you have permission to create branches and push up new commits. HTTPS will require you to enter your username and password each time you push (in Terminal). SSH will be more convenient (because it'll use a pregenerated "keypair" to do the varification) but setting up that pregenerated pair is a bit more involved. It's also well covered in GitHub's docs.

For the rest of this I'm just going to assume we're using HTTPS. The only difference will be that if you set up SSH you won't get any username/password prompts.


Back to it then. Let's clone a repo:

# this will clone the repo into a new directory named <repo name>
$ git clone https://github.com/<organization or owner>/<repo name>.git
# in order to make changes we still need to move into the repo directory
$ cd <repo name>/

Creating a branch

It is generally considered bad practice to make changes directly on the main branch of any repo (usually this is called master and you'll here master used as a stand in for "the main branch" a lot, but it really could be called anything … sometimes you'll see the main branch named develop and in that case master is usually "production" code, that is, stable, tested, reviewed, publicly consumable code). The reasons not to commit directly to master are many, but here are the first couple that occur to me:

  1. master might be hooked up to CI/CD and in this case committing/pushing right to master could cause untested code to go straight into production
  2. committing directly to master doesn't give your peers a chance to review what changes you're making "all together" as a group of related changes
  3. if you ever need to look back through your repo's history (usually to find where/when a bug was introduced) it's harder to break commits up into related changes

So anyway, yeah, create a branch first:

# create the new branch locally, based on the branch you're on (probably master)
$ git checkout --branch <my branch name>
# create a branch with the same name on the remote (named origin by default,
# in this case hosted on GitHub) and set it to be the "tracking branch" for this
# new local branch
$ git push --set-upstream origin <my branch name>

You'll be prompted for a username and password in that second step if you used HTTPS to clone.

The flags (--flag) can be abbreviated like this:

$ git checkout -b <my branch name>
$ git push -u origin <my branch name>

At this point you're all set up to make changes and commit them into your branch.

Making changes

So you've made some changes, and you want to commit them locally, and push them "up" to the remote (GitHub).

Check your status

First, find out "where you are" with git status. All calls to git status will start out like this:

$ git status
On branch <my branch name>

If you've made changes to files that were already in the repo, you'll see something like this:

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)

        modified:   <some modified file name>

no changes added to commit (use "git add" and/or "git commit -a")

If you've added new files to the repo, you'll see something like this:

Untracked files:
  (use "git add <file>..." to include in what will be committed)

        <some new file name>

no changes added to commit (use "git add" and/or "git commit -a")

Running git status on a branch with commited (but not pushed) changes will show something like this:

Your branch is ahead of 'origin/<my branch name>' by <some> commits.
  (use "git push" to publish your local commits)

nothing to commit, working tree clean

If you've both made changes to existing files and added files it'll be a combination of those two.


Also probably worth noting

But maybe not so so important (there's no action to be taken). Running git status on a branch with no local changes will show something like this:

Your branch is up to date with 'origin/<my branch name>'.

nothing to commit, working tree clean

The last line of the git status message will sort of give you a hint of what to do next, but it's kind of mixing two concepts together:

  1. adding files to a commit
  2. creating a commit

You can think of a commit as a kind of manilla envelope. You'll put "files" in it, and then add a message describing the contents of the envelope (files added, changed, removed, etc).

Add files to a commit

If you have new files to add to a commit you have to add them with git add <file name> (you can also use git add . to add all files at once, but this will also add changes from non-new files, more on that below).

Create a commit

Once you've added files to a commit, it's time to "seal the envelope" and add your message about it's contents. Running git commit with no flags will prompt you for a message. To save yourself a little time you can run git commit --message <my message> (or the shorthand git commit -m <my message>).

It's also pretty common to make some changes to already tracked files and want to commit those changes with a message all at once, for this you can use git commit --all --message <my message> (or again, the shorthand git commit -am <my message>).

If you have some new files and some already tracked files and all the changes you want to commit are related you might do this:

$ git add .
$ git commit -m <my message>

But be careful with this, you'll be committing all the files that Git doesn't know about. If you're ever working on security related stuff (or with secrets or tokens or PII) there's a risk that you could unintentionally commit this information to GitHub and then it's in that repositories history forever (or at least, getting it out is a real pain).

Pushing commits to the remote

Once you've created some commits, you'll want to push them to the remote. You'll be prompted for a username and password if you used HTTPS to clone.

$ git push

To recap

Make an "org" directory

$ mkdir ~/Sites/<organization or owner>
$ cd ~/Sites/<organization or owner>

Clone the repo

$ git clone https://github.com/<organization or owner>/<repo name>.git
$ cd <repo name>/

Create a new branch

$ git checkout -b <my branch name> # create a new local branch
$ git push -u origin <my branch name> # create a new remote branch

Get status, add files, commit

$ git status # list added, changed (but not added, a.k.a. tracked), & new files
$ git add <new file name> # add one file
$ git commit <already tracked file name> -m <my message> # commit one file
$ git commit -am <my message> # add all tracked files and commit
$ git add . # add all new files and changed files
$ git commit -m <my message> # commit all added files

Push

$ git push
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment