Git Collaboration Workflows: Master Push, Pull, Fetch & Merge with Real GitHub Examples for Beginners

Complete Git collaboration guide with real terminal output. Learn git push, pull, fetch, merge, GitHub authentication, personal access tokens, and collaborative development workflows for beginners.

19 min read

Ready to master Git collaboration? After learning remote repositories and cloning, it's time to understand the complete collaboration workflow. This tutorial demonstrates real-world Git collaboration using actual terminal sessions, covering authentication, pushing, pulling, and merging changes.

💡

🎯 What You'll Learn: In this comprehensive collaboration guide, you'll discover:

  • How to push local commits to GitHub with proper authentication
  • Setting up GitHub Personal Access Tokens for secure authentication
  • Understanding and resolving authentication failures
  • Making changes through GitHub's web interface
  • The crucial differences between git fetch, git merge, and git pull
  • Managing commit history and understanding ahead/behind status
  • Real collaboration scenarios with detailed explanations
  • Complete terminal output analysis for every command

Prerequisites: Completed the previous tutorial on remote repositories and cloning

🔐 Understanding GitHub Authentication

Why Authentication Matters

Before we can push changes to GitHub, we need to authenticate. GitHub needs to verify:

  • Identity: Who you are
  • Authorization: Whether you have permission to modify this repository
  • Security: Ensuring only authorized users can make changes

Authentication Evolution:

  • Old Method: Username and password (deprecated for security reasons)
  • Current Method: Personal Access Tokens (PAT) or SSH keys
  • Enterprise: Additional methods like SAML, OAuth apps

Why passwords don't work anymore:

  • Passwords can be easily guessed or stolen
  • No granular permissions control
  • Difficult to revoke access for specific applications
  • Personal Access Tokens provide better security and control

🚀 Pushing Your First Changes

Attempting to Push Without Authentication

Let's see what happens when we try to push our changes from the previous tutorial:

[centos9@vbox firstdemoproject 01:47:00]$ git log
commit fd109ec1b5e5cf0f17085cb000004f22a4cccf4b (HEAD -> main)
Author: Owais Abbasi <owais.abbasi9@gmail.com>
Date:   Fri Sep 26 01:46:54 2025 +0500

    add first.txt

commit ba291bf64f69ddedf8d41648bfbce8cbc8e4bf03 (origin/main, origin/HEAD)
Author: Owais Abbasi <81351747+owais-io@users.noreply.github.com>
Date:   Fri Sep 26 01:40:46 2025 +0500

    Initial commit

Understanding the Git Log Output:

Log ComponentExampleMeaning
HEAD -> mainLatest local commitYour current position in the commit history
origin/main, origin/HEADRemote repository positionWhere GitHub thinks the main branch is
Initial commitba291bf commitThe commit created when GitHub repository was initialized

Key Observation: Your local HEAD -> main is one commit ahead of origin/main, origin/HEAD.

The Push Command

[centos9@vbox firstdemoproject 01:47:57]$ git push
Username for 'https://github.com': owais-io
Password for 'https://owais-io@github.com':
remote: {"auth_status":"auth_error","body":"Invalid username or token. Password authentication is not supported for Git operations."}
fatal: Authentication failed for 'https://github.com/owais-io/firstdemoproject.git/'

Command Breakdown:

  • git push - Send local commits to the remote repository
  • Username prompt: Git asks for GitHub username
  • Password prompt: Git asks for authentication (this will fail)

Understanding Authentication Failure

The error message tells us everything we need to know:

Error Analysis:

  • "auth_status":"auth_error" - Authentication failed
  • "Invalid username or token" - Credentials were rejected
  • "Password authentication is not supported" - GitHub no longer accepts passwords for Git operations

Why This Happens: GitHub disabled password authentication for Git operations to improve security. You must use Personal Access Tokens instead.

🔑 Setting Up Personal Access Tokens

Creating a Personal Access Token

To authenticate with GitHub, you need to create a Personal Access Token (PAT):

Step-by-Step Token Creation:

  1. Go to GitHub Settings: Click your profile photo → Settings
  2. Navigate to Developer Settings: Scroll down to "Developer settings"
  3. Personal Access Tokens: Click "Personal access tokens" → "Tokens (classic)"
  4. Generate New Token: Click "Generate new token (classic)"
  5. Token Configuration:
    • Note: Enter a description (e.g., "Git operations for learning")
    • Expiration: Choose the shortest reasonable time (better security)
    • Scopes: Select "repo" for full repository access
  6. Generate and Save: Click "Generate token" and immediately copy and save it securely
⚠️

🚨 Critical Security Note:

  • Personal Access Tokens are like passwords - treat them securely
  • GitHub shows the token only once - save it immediately
  • Never share tokens in code, screenshots, or public places
  • Use the shortest reasonable expiration time
  • Regenerate tokens periodically for better security

Successful Push with Personal Access Token

[centos9@vbox firstdemoproject 01:56:33]$ git push
Username for 'https://github.com': owais-io
Password for 'https://owais-io@github.com':
Enumerating objects: 4, done.
Counting objects: 100% (4/4), done.
Delta compression using up to 4 threads
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 292 bytes | 292.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0), pack-reused 0 (from 0)
To https://github.com/owais-io/firstdemoproject.git
   ba291bf..fd109ec  main -> main

Command Success Breakdown:

Output LineProcessWhat's Happening
Enumerating objects: 4PreparationGit identifies 4 objects to transfer
Counting objects: 100% (4/4)ProgressAll objects counted and ready
Delta compression using up to 4 threadsOptimizationGit compresses data for efficient transfer
Writing objects: 100% (3/3)UploadObjects successfully sent to GitHub
ba291bf..fd109ec main -> mainCompletionUpdated remote main from ba291bf to fd109ec

Important: When prompted for password, use your Personal Access Token, not your GitHub password!

Verifying Synchronization

[centos9@vbox firstdemoproject 01:56:56]$ git status
On branch main
Your branch is up to date with 'origin/main'.

nothing to commit, working tree clean

Status Changes:

  • Before Push: "ahead of 'origin/main' by 1 commit"
  • After Push: "up to date with 'origin/main'"
  • Meaning: Your local and remote repositories are now synchronized

📝 Making Multiple Changes

Creating and Modifying Files

Let's create more content to demonstrate advanced workflows:

[centos9@vbox firstdemoproject 01:58:09]$ cat <<EOF >> first.txt
Demo world
EOF

[centos9@vbox firstdemoproject 01:59:13]$ cat first.txt
hello world
Demo world

Command Explanation:

  • cat <<EOF >> first.txt - Append content to existing file (note >> for append vs > for overwrite)
  • Content: Adding "Demo world" to the existing "hello world"

Checking Status of Modified File

[centos9@vbox firstdemoproject 01:59:17]$ git status
On branch main
Your branch is up to date with 'origin/main'.

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:   first.txt

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

New Status Understanding:

  • "Changes not staged for commit" - File is tracked but changes aren't ready for commit
  • "modified: first.txt" - Git detected changes to existing file
  • Git suggestions: Helpful commands for next steps

Staging and Committing Modifications

[centos9@vbox firstdemoproject 01:59:20]$ git add .

[centos9@vbox firstdemoproject 01:59:27]$ git status
On branch main
Your branch is up to date with 'origin/main'.

Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
	modified:   first.txt
[centos9@vbox firstdemoproject 01:59:31]$ git commit -m "updated first.txt"
[main 6711dca] updated first.txt
 1 file changed, 1 insertion(+)

Commit Output Analysis:

  • [main 6711dca] - New commit hash starts with 6711dca
  • 1 file changed, 1 insertion(+) - Statistics showing what changed
  • Notice: No "create mode" since this is a modification, not a new file

Adding a Second File

[centos9@vbox firstdemoproject 01:59:44]$ touch second.txt

[centos9@vbox firstdemoproject 01:59:56]$ cat <<EOF > second.txt
> hello world in second file
> EOF

[centos9@vbox firstdemoproject 02:00:16]$ cat second.txt
hello world in second file

Staging and Committing Multiple Changes

[centos9@vbox firstdemoproject 02:00:25]$ git status
On branch main
Your branch is ahead of 'origin/main' by 1 commit.
  (use "git push" to publish your local commits)

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

nothing added to commit but untracked files present (use "git add" to track)

Complex Status Explanation:

  • "ahead of 'origin/main' by 1 commit" - Previous commit hasn't been pushed yet
  • "Untracked files: second.txt" - New file needs to be tracked
  • Mixed state: Some changes committed locally, others not staged yet
[centos9@vbox firstdemoproject 02:00:28]$ git add .

[centos9@vbox firstdemoproject 02:00:30]$ git commit -m "added second.txt"
[main def41e6] added second.txt
 1 file changed, 1 insertion(+)
 create mode 100644 second.txt

[centos9@vbox firstdemoproject 02:00:40]$ git status
On branch main
Your branch is ahead of 'origin/main' by 2 commits.
  (use "git push" to publish your local commits)

nothing to commit, working tree clean

Key Observation: Now we're "ahead of 'origin/main' by 2 commits"

📊 Understanding Commit History

Examining Multiple Commits

[centos9@vbox firstdemoproject 02:00:51]$ git log
commit def41e6fe0c46bcbfd847e3452ff211cde783a12 (HEAD -> main)
Author: Owais Abbasi <owais.abbasi9@gmail.com>
Date:   Fri Sep 26 02:00:38 2025 +0500

    added second.txt

commit 6711dcae4f7539f7b6500ea55ea5b0dab82914e5
Author: Owais Abbasi <owais.abbasi9@gmail.com>
Date:   Fri Sep 26 01:59:39 2025 +0500

    updated first.txt

commit fd109ec1b5e5cf0f17085cb000004f22a4cccf4b (origin/main, origin/HEAD)
Author: Owais Abbasi <owais.abbasi9@gmail.com>
Date:   Fri Sep 26 01:46:54 2025 +0500

    add first.txt

commit ba291bf64f69ddedf8d41648bfbce8cbc8e4bf03
Author: Owais Abbasi <81351747+owais-io@users.noreply.github.com>
Date:   Fri Sep 26 01:40:46 2025 +0500

    Initial commit

Analyzing Commit History Structure

CommitStatusDescription
def41e6 (HEAD -> main)Local onlyLatest commit - added second.txt
6711dcaLocal onlyModified first.txt content
fd109ec (origin/main)SyncedLast commit that GitHub has
ba291bfSyncedInitial commit from GitHub

📤 Pushing Multiple Commits

Understanding Push Syntax

[centos9@vbox firstdemoproject 02:01:52]$ git push origin master
error: src refspec master does not match any
error: failed to push some refs to 'https://github.com/owais-io/firstdemoproject.git'

Error Analysis:

  • "src refspec master does not match any" - There's no 'master' branch
  • Why it failed: This repository uses 'main' as the default branch, not 'master'

Correct Push Syntax

[centos9@vbox firstdemoproject 02:01:52]$ git push origin main
Username for 'https://github.com': owais-io
Password for 'https://owais-io@github.com':
Enumerating objects: 8, done.
Counting objects: 100% (8/8), done.
Delta compression using up to 4 threads
Compressing objects: 100% (4/4), done.
Writing objects: 100% (6/6), 542 bytes | 542.00 KiB/s, done.
Total 6 (delta 1), reused 0 (delta 0), pack-reused 0 (from 0)
remote: Resolving deltas: 100% (1/1), done.
To https://github.com/owais-io/firstdemoproject.git
   fd109ec..def41e6  main -> main

Command Best Practices:

  • git push origin main - Explicitly specify remote and branch
  • origin - The remote repository name (GitHub)
  • main - The branch name
  • Alternative: git push works when tracking is set up, but being explicit is clearer

Push Output Deep Dive

Output ComponentValueSignificance
Objects to transfer8 totalMore objects than before due to multiple commits
New objects written6 objectsTwo new commits plus associated data
Delta resolution100% (1/1)Git optimized the transfer by using differences
Branch updatefd109ec..def41e6GitHub updated from fd109ec to def41e6

🌐 Collaboration Through GitHub Web Interface

Making Changes Online

To simulate collaboration, let's make changes through GitHub's web interface:

Steps to Edit Files on GitHub:

  1. Navigate to Repository: Go to your GitHub repository page
  2. Select File: Click on first.txt to view it
  3. Edit Mode: Click the pencil icon (edit button)
  4. Make Changes: Add a new line to the file
  5. Commit Changes:
    • Add commit message (e.g., "changes from online editor")
    • Select "Commit directly to the main branch"
    • Click "Commit Changes"

Why This Simulates Collaboration: This represents what happens when a teammate makes changes to the shared repository while you're working locally.

🔄 Understanding Fetch vs Pull vs Merge

Detecting Remote Changes

After making changes on GitHub, let's check our local repository:

[centos9@vbox firstdemoproject 02:12:28]$ git status
On branch main
Your branch is up to date with 'origin/main'.

nothing to commit, working tree clean

Important Question: Why doesn't Git show the changes we made on GitHub?

Why Local Git Doesn't Know About Remote Changes:

Git doesn't automatically monitor remote repositories. Your local Git only knows what it knew the last time it communicated with GitHub. To detect remote changes, you need to explicitly ask Git to check.

Analogy: It's like checking your mailbox - mail might arrive, but you won't know until you physically check the mailbox.

Git Fetch - Checking for Updates

[centos9@vbox firstdemoproject 02:12:50]$ git fetch
remote: Enumerating objects: 5, done.
remote: Counting objects: 100% (5/5), done.
remote: Compressing objects: 100% (3/3), done.
remote: Total 3 (delta 0), reused 0 (delta 0), pack-reused 0 (from 0)
Unpacking objects: 100% (3/3), 1002 bytes | 334.00 KiB/s, done.
From https://github.com/owais-io/firstdemoproject
   def41e6..1735faa  main       -> origin/main

Git Fetch Explanation:

  • git fetch - Download changes from remote repository without merging them
  • Purpose: Update your local knowledge of remote repository state
  • Safe operation: Doesn't change your working files

What Fetch Downloads vs What It Doesn't Change

[centos9@vbox firstdemoproject 02:13:09]$ cat first.txt
hello world
Demo world

[centos9@vbox firstdemoproject 02:13:13]$ ls -ahl
total 16K
drwxr-xr-x. 3 centos9 centos9   70 Sep 26 01:59 .
drwxr-xr-x. 4 centos9 centos9   58 Sep 26 01:55 ..
-rw-r--r--. 1 centos9 centos9   23 Sep 26 01:59 first.txt
drwxr-xr-x. 8 centos9 centos9 4.0K Sep 26 02:12 .git
-rw-r--r--. 1 centos9 centos9   49 Sep 26 01:44 README.md
-rw-r--r--. 1 centos9 centos9   27 Sep 26 02:00 second.txt

Key Insight: After git fetch:

  • Remote changes downloaded: Stored in .git folder
  • Working files unchanged: Your files still show old content
  • Git knows about updates: But hasn't applied them to working directory

Git Merge - Applying Remote Changes

[centos9@vbox firstdemoproject 02:13:35]$ git merge
Updating def41e6..1735faa
Fast-forward
 first.txt | 1 +
 1 file changed, 1 insertion(+)

[centos9@vbox firstdemoproject 02:13:39]$ cat first.txt
hello world
Demo world
changes from online editor

Git Merge Results:

  • "Fast-forward" - Simple merge without conflicts
  • "1 file changed, 1 insertion(+)" - Statistics of changes applied
  • File content updated: Now shows the line added through GitHub

Git Pull - Fetch + Merge Combined

For the next demonstration, let's make another change on GitHub and use git pull:

[centos9@vbox firstdemoproject 02:15:27]$ git pull
remote: Enumerating objects: 5, done.
remote: Counting objects: 100% (5/5), done.
remote: Compressing objects: 100% (2/2), done.
remote: Total 3 (delta 1), reused 0 (delta 0), pack-reused 0 (from 0)
Unpacking objects: 100% (3/3), 952 bytes | 476.00 KiB/s, done.
From https://github.com/owais-io/firstdemoproject
   1735faa..ee0fbd5  main       -> origin/main
Updating 1735faa..ee0fbd5
Fast-forward
 second.txt | 1 +
 1 file changed, 1 insertion(+)

[centos9@vbox firstdemoproject 02:15:37]$ cat second.txt
hello world in second file
change from github

🔍 Fetch vs Pull vs Merge Comparison

CommandWhat It DoesWhen to UseSafety Level
git fetchDownloads remote changes, doesn't modify working filesCheck what's new before deciding to mergeVery Safe
git mergeCombines fetched changes with current branchAfter fetch, when ready to apply changesModerate
git pullFetch + Merge in one commandWhen you're confident about merging immediatelyRequires Caution

Best Practices for Collaboration

Recommended Workflow:

  1. Before Starting Work: git pull to get latest changes
  2. During Development: Make commits locally as needed
  3. Before Pushing:
    • git fetch to check for remote updates
    • git merge if there are updates
    • Resolve any conflicts
    • git push to share your changes
  4. Regular Updates: git fetch periodically to stay informed

Why This Approach Works:

  • Reduces merge conflicts
  • Keeps your local repository current
  • Prevents surprise conflicts during push
  • Maintains clean commit history

🎯 Key Takeaways

✅ Essential Collaboration Concepts Mastered

  1. Authentication: Set up and use Personal Access Tokens for secure GitHub access

  2. Push Workflow: Successfully push local commits to remote repositories

  3. Commit History: Understand how local and remote histories diverge and sync

  4. Remote Changes: Handle changes made by others (or through GitHub interface)

  5. Fetch vs Pull vs Merge: Know when and how to use each command safely

  6. Branch Awareness: Understand the difference between 'main' and 'master' branches

  7. Status Interpretation: Read Git status messages to understand repository state

  8. Collaboration Safety: Use fetch first to avoid unexpected merges

🎉 Congratulations! You have successfully mastered:

  • ✅ GitHub authentication with Personal Access Tokens
  • ✅ Pushing local changes to remote repositories
  • ✅ Understanding ahead/behind status
  • ✅ Making changes through GitHub's web interface
  • ✅ The crucial differences between fetch, pull, and merge
  • ✅ Safe collaboration workflows to avoid conflicts
  • ✅ Complete understanding of local vs remote repository states

You now have the essential skills for Git collaboration and are ready for team development!

💬 Discussion

How did your first collaboration experience with Git and GitHub go?

  • What was most challenging about the push/pull workflow?
  • Did you encounter any authentication issues with Personal Access Tokens?
  • Which approach do you prefer: fetch + merge or pull, and why?
  • What questions do you have about handling conflicts or team collaboration?

📋 Git Collaboration Commands Cheat Sheet

CommandPurposeExample Usage
git pushSend local commits to remote repositorygit push origin main
git fetchDownload remote changes without merginggit fetch origin
git mergeApply fetched changes to current branchgit merge
git pullFetch and merge in one commandgit pull origin main
git logView commit historygit log --oneline
git statusCheck repository and file statusgit status
Owais

Written by Owais

I'm an AIOps Engineer with a passion for AI, Operating Systems, Cloud, and Security—sharing insights that matter in today's tech world.

I completed the UK's Eduqual Level 6 Diploma in AIOps from Al Nafi International College, a globally recognized program that's changing careers worldwide. This diploma is:

  • ✅ Available online in 17+ languages
  • ✅ Includes free student visa guidance for Master's programs in Computer Science fields across the UK, USA, Canada, and more
  • ✅ Comes with job placement support and a 90-day success plan once you land a role
  • ✅ Offers a 1-year internship experience letter while you study—all with no hidden costs

It's not just a diploma—it's a career accelerator.

👉 Start your journey today with a 7-day free trial

Related Articles

Continue exploring with these handpicked articles that complement what you just read

More Reading

One more article you might find interesting