<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Joe</title>
    <description>The latest articles on DEV Community by Joe (@altjoe).</description>
    <link>https://dev.to/altjoe</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4090232%2Fa032ccb8-b2a3-473a-9703-f0fdf3316302.png</url>
      <title>DEV Community: Joe</title>
      <link>https://dev.to/altjoe</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/altjoe"/>
    <language>en</language>
    <item>
      <title>Understanding the Git Workflow: Working Directory, Staging, Commit and Push</title>
      <dc:creator>Joe</dc:creator>
      <pubDate>Sun, 23 Aug 2026 02:58:05 +0000</pubDate>
      <link>https://dev.to/altjoe/understanding-the-git-workflow-working-directory-staging-commit-and-push-5fgo</link>
      <guid>https://dev.to/altjoe/understanding-the-git-workflow-working-directory-staging-commit-and-push-5fgo</guid>
      <description>&lt;p&gt;Working through a practical reference to moving a change through Git took me through the process of taking a single change from my local computer, committing it in Git, and pushing it to GitHub where others would be able to see it. This was written for complete Git Novices and so I approached it without any prior experience of using Git.&lt;/p&gt;

&lt;p&gt;By the end, you will be able to move a change through all four Git stages and confirm it's visible on GitHub with a clear commit history.&lt;/p&gt;

&lt;h2&gt;
  
  
  Who This Is For
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Anyone that want to work with Git in the terminal&lt;/li&gt;
&lt;li&gt;Users who find &lt;code&gt;git add&lt;/code&gt;, &lt;code&gt;git commit&lt;/code&gt;, and &lt;code&gt;git push&lt;/code&gt; unclear&lt;/li&gt;
&lt;li&gt;No prior Git experience required&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Git installed (&lt;code&gt;git --version&lt;/code&gt; to check)&lt;/li&gt;
&lt;li&gt;A terminal or command-line application&lt;/li&gt;
&lt;li&gt;A &lt;a href="https://github.com/login" rel="noopener noreferrer"&gt;GitHub account&lt;/a&gt; (create one if needed)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We'll use a small &lt;strong&gt;sales data&lt;/strong&gt; project as a running example. You do &lt;strong&gt;not&lt;/strong&gt; need Python or Pandas installeda as we will be only tracking files, not running code.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Four-Stage Flow
&lt;/h2&gt;

&lt;p&gt;Every change travels in one direction:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Project Directory → Staging Area → Local Git Repository → Remote  Github Repository&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Project directory&lt;/strong&gt;: where everything is worked on&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Staging area&lt;/strong&gt;: choosing what goes in&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Local Git Repository(Commit)&lt;/strong&gt;: your historical record for everything worked on&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Remote Github Repository(Push)&lt;/strong&gt;: share it so collaborators can see it&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Setup: Initialize a Repository
&lt;/h2&gt;

&lt;p&gt;Create a project folder and make it a Git repository:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;mkdir &lt;/span&gt;monthly-sales
&lt;span class="nb"&gt;cd &lt;/span&gt;monthly-sales
git init
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Expected output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Initialized empty Git repository in /path/to/monthly-sales/.git/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;git init&lt;/code&gt; creates a hidden &lt;code&gt;.git&lt;/code&gt; folder where Git stores the entire history. From now on, Git watches this folder.&lt;/p&gt;

&lt;h3&gt;
  
  
  Usage
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;1. Working Directory (Untracked Files)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Create a raw data file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"date,region,revenue"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; sales_data.csv
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"2026-01-01,East,1200"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; sales_data.csv
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Check its status:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git status
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Expected output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;On branch main
No commits yet
Untracked files:
  (use "git add &amp;lt;file&amp;gt;..." to include in what will be committed)
        sales_data.csv
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;&lt;em&gt;Untracked&lt;/em&gt;&lt;/strong&gt; means Git can see the file but isn't following it yet. This is the default for new files.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Staging Area (Choose What to Commit)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Stage the file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git add sales_data.csv
git status
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Expected output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;On branch main
No commits yet
Changes to be committed:
  (use "git rm --cached &amp;lt;file&amp;gt;..." to unstage)
        new file:   sales_data.csv
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The label changes from Untracked files to &lt;strong&gt;&lt;em&gt;Changes to be committed&lt;/em&gt;&lt;/strong&gt;. The file is staged but not yet saved to history.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;PRO TIP&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If you edit two unrelated files (e.g., raw data and a cleaning script), you don't have to commit them together. Stage and commit one, then come back for the other. This keeps your history readable.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;NOTE&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;git add .&lt;/code&gt; stages everything at once.&lt;br&gt;
Always run &lt;code&gt;git status&lt;/code&gt; first so you know exactly what that includes.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;3. Commit (Local Snapshot)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Create a commit:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git commit &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s2"&gt;"Add raw January sales data"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;View the history:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git log
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Expected output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;commit 6f3a1e2c9d8b4a17f0e3c5d9a2b1e8f7c3d4a5b6
Author: Some Rando &amp;lt;somerando@example.com&amp;gt;
Date:   Sat Aug 22 10:15:03 2026 +0000

    Add raw January sales data
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A &lt;strong&gt;&lt;em&gt;commit&lt;/em&gt;&lt;/strong&gt; is a permanent snapshot of everything staged, saved with a message, timestamp, and author details. It's local until you push.Commit messages have two readers: your future self and collaborators.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;PRO TIP&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Writing Good Commit Messages:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use the imperative mood ("Add", "Fix", "Update")&lt;/li&gt;
&lt;li&gt;Say specifically what changed&lt;/li&gt;
&lt;li&gt;Explain why when it isn't obvious&lt;/li&gt;
&lt;li&gt;Cover one logical change&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Weak&lt;/th&gt;
&lt;th&gt;Strong&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;update&lt;/td&gt;
&lt;td&gt;Add February revenue row to raw sales data&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;fix&lt;/td&gt;
&lt;td&gt;Fix currency parsing for negative revenue values&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;changes&lt;/td&gt;
&lt;td&gt;Drop rows with missing region before export&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;wipe&lt;/td&gt;
&lt;td&gt;Add first draft of sales cleaning script&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;For longer commit messages, run &lt;code&gt;git commit&lt;/code&gt; without &lt;code&gt;-m&lt;/code&gt; to open your editor. Use a short summary line, a blank line, then a detailed body:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Fix currency parsing for negative revenue values

Regions reporting refunds submit revenue as "-120.00", which the
previous parser rejected as invalid. This adds a check for a
leading minus sign before the numeric conversion.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Demonstration: Separate Commits for Separate Changes&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Make two changes—one to an existing file and one new file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"2026-01-02,West,950"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; sales_data.csv
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"import pandas as pd"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; clean_sales.py
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"df = pd.read_csv('sales_data.csv')"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; clean_sales.py
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"df.to_csv('clean_sales.csv', index=False)"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; clean_sales.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Check status:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git status
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Expected output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Changes not staged for commit:
        modified:   sales_data.csv

Untracked files:
        clean_sales.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Stage and commit them separately:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git add sales_data.csv
git commit &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s2"&gt;"Add February revenue row to raw sales data"&lt;/span&gt;

git add clean_sales.py
git commit &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s2"&gt;"Add script to clean and export sales data"&lt;/span&gt;

git log
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;git log&lt;/code&gt; now shows three commits, each describing one specific change.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Push (GitHub)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Connect your local repository to an empty GitHub repository:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git remote add origin https://github.com/your-username/monthly-sales.git
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Push:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git push &lt;span class="nt"&gt;-u&lt;/span&gt; origin main
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Expected output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Enumerating objects: 9, done.
Writing objects: 100% (9/9), done.
To https://github.com/your-username/monthly-sales.git
 * [new branch]      main -&amp;gt; main
branch 'main' set up to track 'origin/main'.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;origin&lt;/code&gt; is the nickname for your GitHub URL.&lt;br&gt;
&lt;code&gt;main&lt;/code&gt; is the branch being pushed.&lt;br&gt;
&lt;code&gt;-u&lt;/code&gt; links your local &lt;code&gt;main&lt;/code&gt; to &lt;code&gt;origin/main&lt;/code&gt;, so future pushes can just be &lt;code&gt;git push&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Verify on GitHub:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;sales_data.csv&lt;/code&gt; and &lt;code&gt;clean_sales.py&lt;/code&gt; are present&lt;/li&gt;
&lt;li&gt;The commit history shows three separate, clearly labeled commits&lt;/li&gt;
&lt;li&gt;Locally, &lt;code&gt;git status&lt;/code&gt; reports nothing to commit (working tree clean)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That's the success signal: a local change, visible on GitHub, with a history that explains itself.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Troubleshooting&lt;/strong&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Symptom&lt;/th&gt;
&lt;th&gt;Cause and Fix&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;git commit&lt;/code&gt; runs, but GitHub shows nothing&lt;/td&gt;
&lt;td&gt;Commits are local only. Run &lt;code&gt;git push&lt;/code&gt; to upload.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;nothing to commit, working tree clean&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Changes must be staged. Run &lt;code&gt;git add &amp;lt;file&amp;gt;&lt;/code&gt;, then &lt;code&gt;git status&lt;/code&gt;.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;git add .&lt;/code&gt; staged files you didn't want&lt;/td&gt;
&lt;td&gt;Run &lt;code&gt;git status&lt;/code&gt; first. Use a &lt;code&gt;.gitignore&lt;/code&gt; to exclude secrets, &lt;code&gt;.env&lt;/code&gt;, etc.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Secrets committed by mistake&lt;/td&gt;
&lt;td&gt;Treat them as compromised and rotate. Removing them later doesn't erase history.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;fatal: No configured push destination&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;No remote is set. Run &lt;code&gt;git remote add origin &amp;lt;url&amp;gt;&lt;/code&gt; before pushing.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Vague commit messages ("update", "fix stuff")&lt;/td&gt;
&lt;td&gt;Not an error, but unreadable history. Follow the commit message guidelines.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Quick Reference&lt;/strong&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Stage&lt;/th&gt;
&lt;th&gt;Command&lt;/th&gt;
&lt;th&gt;Result&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Working Directory&lt;/td&gt;
&lt;td&gt;create/edit a file&lt;/td&gt;
&lt;td&gt;Untracked or modified&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Staging Area&lt;/td&gt;
&lt;td&gt;&lt;code&gt;git add &amp;lt;file&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;"Changes to be committed"&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Local Repository&lt;/td&gt;
&lt;td&gt;&lt;code&gt;git commit -m "msg"&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Permanent local snapshot&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Remote Repository&lt;/td&gt;
&lt;td&gt;&lt;code&gt;git push&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Visible on GitHub&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;When in doubt, always run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git status
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Try It Yourself
&lt;/h3&gt;

&lt;p&gt;In a new, empty folder:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Repeat all four stages with a data file or script of your own.&lt;/li&gt;
&lt;li&gt;Edit two unrelated files in the same session.&lt;/li&gt;
&lt;li&gt;Stage and commit them as two separate commits, each with a specific, imperative-mood message.&lt;/li&gt;
&lt;li&gt;Run &lt;code&gt;git log&lt;/code&gt; and confirm each commit describes exactly one change clearly enough that a teammate wouldn't need to ask what it means.&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>beginners</category>
      <category>git</category>
      <category>tutorial</category>
    </item>
  </channel>
</rss>
