DEV Community


Posted on


A Git Individual Workflow WalkThrough

Git and its workflows can be initially hard concepts to wrap our heads around.

Git is a version control system that lets us keep track of and manage code history. Github is a cloud-based hosting service that helps to manage Git repositories (repos).

Some cool things about Git are that it's based off of a branching model and it's mostly local. Github, on the other hand, is exclusively remote/cloud-based, which allows different people to view, clone, and collaborate with our code.

Flow of Data with Git and Github

Our workflows are going to follow the interaction between our machine (local changes via Git) and the hosting service (remote changes stored via Github history).
For the purposes of simplicity, from this point onwards we're going to use 'local' and 'remote' keywords to refer to our local machines and remote repositories/branches.

Data can be considered within two types:
(a) dynamic instance data, such as code files and their contents
(b) static metadata, such as our branches and commits with user information (or 'git blame' data)

At a high level we could say that our data moves from local locations to remote locations and vise versa

Movement of Data Flow Chart

Walkthrough of personal workflow

Now what happens when we make changes locally and how do we do that?
After we copy the remote's repository with git clone, we are able to work within Git's branching system locally.

When we git pull we're pulling a copy of a specific branch from the remote repository to our local workspace. If there haven't been any changes to the remote repository, then when we git pull we will get an 'Already up to date' message.

user@ repo-name % git pull origin main
 * branch            main       -> FETCH_HEAD
Already up to date.
Enter fullscreen mode Exit fullscreen mode

We should git pull only the remote branch name that matches the local branch we are currently in.
We can check which branch we're currently located in with git branch.

user@ repo-name % git branch
* master
Enter fullscreen mode Exit fullscreen mode

Imagine your master or main branch is the trunk of a tree. Whatever branches we create out of that trunk will be almost like draft branches because they will only exist in our local workspace and then eventually into our local repository, where those draft branches will be reviewed and edited.

When we git checkout -b any-new-branch-name we're creating new local branches off of the master/main root branch and we're moving to that branch.

user@ repo-name % git checkout -b any-new-branch     
Switched to a new branch 'any-new-branch'
Enter fullscreen mode Exit fullscreen mode

We can do git branch again to sanity-check that we're in fact in our new branch

user@ repo-name % git branch
* any-new-branch
Enter fullscreen mode Exit fullscreen mode

Our new branch will end up tracking the version history of our changes via commits. But before we commit to our official remote repository history, we must stage those changes in our index. We can check which files are staged via git status. git status displays files that have (or have not) been changed in the working directory and the staged directory.

If we've made no changes to any files, running git status will tell us that we have a clean working tree

user@ repo-name % git status
On branch any-new-branch
nothing to commit, working tree clean
Enter fullscreen mode Exit fullscreen mode

So lets add some code changes and then see what git status looks like.

user@ repo-name % git status
On branch any-new-branch
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
    modified:   src/components/Header.js
        modified:   src/components/MainContainer.j

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

Any modification that we make to a file will show up under our workspace area(located after 'changes not staged for commit' in red). In order to add those changes to our index, we must run git add <file-name>.

user@ repo-name % git status
On branch any-new-branch
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
    modified:   src/components/Header.js

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
    modified:   src/components/MainContainer.js

Enter fullscreen mode Exit fullscreen mode

git add adds new or modified files (from our workspace) to our staging area (located after 'changes to be committed' in green). git add gives us the benefit of choice in deciding which files and changes we would like to commit. Based on Github's Git Guides, commits should be logical, atomic units of change. Tech teams usually organize their commits based on whichever rule of logic their organization/company practices. An example rule may be that each commit must contain all changes made to an individual file or that each commit must bucket one specific value within a feature. Why implement logical rules for commits? A clean commit history is usually easy to read, helpful for debugging, and helpful for understanding which changes we might end up needing to revert.

To add our changes to an individual commit and create an easy-to-understand commit message, we run git commit -m "any commit message"

user@ repo-name % git commit -m "perf: cleanup/removed debugging comments"
[any-new-branch 71a72da] perf: cleanup/removed debugging comments
 1 file changed, 1 insertion(+), 1 deletion(-)
Enter fullscreen mode Exit fullscreen mode

Commit messages should describe what kind of change we've made to our code. In the above example, our commit message indicates that our changes included file cleanup of removing some sudo-code that was no longer needed. The perf header indicates that the change we made was a removal. This perf header is one of several semantic-release headers and footers that we can add to our commit message to indicate the type of change we've made to our code (addition, removal, patch/fix, or breaking change). To read more on semantic headers, you can read more here.

After we've committed our changes, we can git log to view our commit history and sanity check that our commit is in the right place in history. The log commits are in order of most to least recent, so our most recent commit should be at the top, which we can see in the code below.

commit 71a72da43ca6cdd9774c8abf00a96fb3f6c6d0b9 (HEAD -> any-new-branch)
Author: Adeline Almanzar <>
Date:   Sun Feb 13 11:31:50 2022 -0800

    perf: cleanup/removed debugging comments

commit 84c056344662503041c6fd3d5365f805dfca08e8 (master)
Author: Adeline Almanzar <>
Date:   Mon Feb 7 20:38:54 2022 -0800

    third deliverable
Enter fullscreen mode Exit fullscreen mode

Each commit in the log will have a commit ID, information on the author of the commit, the date & time of the commit, and the commit message.

Now that we've committed our changes and done our sanity-checking, at this point we can keep going through the changes workflow to continue committing our changes to our local repository.

Once our local repository is at a ready-enough state for our team's review and/or collaboration, we can push our changes to the remote repository with git push origin <branch-name>.

user@ repo-name % git push origin any-new-branch
Enumerating objects: 29, done.
Counting objects: 100% (29/29), done.
Delta compression using up to 8 threads
Compressing objects: 100% (28/28), done.
Writing objects: 100% (28/28), 286.05 KiB | 3.11 MiB/s, done.
Total 28 (delta 0), reused 0 (delta 0), pack-reused 0
   84c0563..71a72da  any-new-branch -> any-new-branch
Enter fullscreen mode Exit fullscreen mode

git push will send all of our local repository's commits and branches to the remote repository (in Github). When we sign into Github and visit the remote repository, we should be able to create a new pull request(PR). We can think of our pull request as a form that we submit to our team with the request to officially merge our changes to the remote branch we originally branched-off of. PRs enable us to share the purpose of our code changes in layman's terms. They also enable our team members access to review our changes and make changes themselves (stay tuned for my next blog post on collaborative workflows).

TLDR: Personal Workflow Summary

  1. git clone repo-link && cd repo-name: make a clone/local copy of the remote repository and move into it
  2. git branch: view current branch & view all branches in our local repository
  3. git pull origin master: pull remote master branch data to our local master branch
  4. git checkout -b new-branch-name: create a new local branch and move to that branch
  5. git branch: sanity check that we're in proper new branch
  6. Make code changes
  7. git status: shows what files have had changes made & shows whether our files have been staged or not (green for yes, red for no)
  8. git add filePath/wanting/toStage.txt: add files, via their file paths, to the staging/index area
  9. git status: sanity check that only preferred files are staged/added to index
  10. git commit -m "any commit message": snapshot currently staged changes via a singular commit & write concise message
  11. git log: view our commit history to sanity check that our most recent commit is at the top of the history list
  12. git push origin new-branch: push our local new-branch and its data to the remote space (Github)
  13. Create pull request on Github
  14. git branch: sanity check that current branch is still new-branch
  15. git pull origin new-branch: pull (to our local new-branch) any changes that might have been added from the remote new-branch
  16. (a) If making changes to the same branch, repeat steps 6-12 (b) If making changes to a different branch, repeat steps 5-12


  1. Another git workflow & commands explanation
  2. A git commands cheat sheet
  3. Git Guides

Top comments (0)