# 60 Days DevOps Challenge: Day 3

### **Initial Tasks:**

✅ Install **Git** on your system: [*Git Installation*](https://git-scm.com/downloads?utm_source=www.learnxops.com&utm_medium=referral&utm_campaign=git-github-basics-branching-merging-prs)

  
✅ **Configure** your **Git username** and **email**:

```plaintext
git config --global user.name "Your Name"
git config --global user.email "your@email.com"
```

  
✅ Create a new folder and **initialize a Git repository:**

```plaintext
mkdir git-project && cd git-project
git init
```

  
✅ Create two files (`index.html`, `style.css`), add content, and commit:

```plaintext
touch index.html style.css
git add .
git commit -m "Initial commit"
```

  
✅ **Modify** `index.html`, **check changes**, and **make another commit**:

```plaintext
git status
git diff
git add index.html
git commit -m "Updated index.html"
```

  
✅ **Check commit history** using:

```plaintext
git log --oneline
```

  
✅ Create a [***GitHub Repository***](https://github.com/new?utm_source=www.learnxops.com&utm_medium=referral&utm_campaign=git-github-basics-branching-merging-prs), add a remote, and push:

```plaintext
git remote add origin https://github.com/yourusername/git-project.git
git branch -M main
git push -u origin main
```

### ***Challenge 1****:* ***Fork and clone an open-source project (***[***Sample Project Link***](https://github.com/sd031/eks-auto-mode-workshop?utm_source=www.learnxops.com&utm_medium=referral&utm_campaign=git-github-basics-branching-merging-prs)***)***

###### **Step 1: Fork the Repository**

1. **Go to the repository link:**  
    👉 [*EKS Auto Mode Workshop*](https://github.com/sd031/eks-auto-mode-workshop?utm_source=www.learnxops.com&utm_medium=referral&utm_campaign=git-github-basics-branching-merging-prs)
    
2. **Click the "Fork" button** (top right) to create a copy under your GitHub account
    

###### **Step 2: Clone the Forked Repository**

**Once you've forked the repository, run:**

**(**Replace `YOUR_GITHUB_USERNAME` with your actual GitHub username.**)**

```plaintext
MacBook-Pro musaveer_work % git clone https://github.com/MusaveerHolalkere25/eks-auto-mode-workshop.git
```

**Bonus** 💡 **:** If you want to **sync future updates** from the original repository, **navigate into the Project Directory &** Set the Upstream Repository, and run:

```plaintext
cd eks-auto-mode-workshop
git remote add upstream https://github.com/MusaveerHolalkere25/eks-auto-mode-workshop.git
```

**Verify via running:**

```plaintext
MacBook-Pro eks-auto-mode-workshop % git remote -v
origin	https://github.com/MusaveerHolalkere25/eks-auto-mode-workshop.git (fetch)
origin	https://github.com/MusaveerHolalkere25/eks-auto-mode-workshop.git (push)
upstream	https://github.com/sd031/eks-auto-mode-workshop.git (fetch)
upstream	https://github.com/sd031/eks-auto-mode-workshop.git (push)
```

**To fetch and merge updates from the original repo:**

```plaintext
git fetch upstream
git merge upstream/main
```

### ***Challenge 2****:* ***Create a new branch (***`feature-branch`***), switch, and commit changes.***

##### **Step 1: Create a New Branch and Switch to It:**

```plaintext
git checkout -b feature-branch
```

##### **Step 2: Verify the Active Branch**

```plaintext
MacBook-Pro eks-auto-mode-workshop % git branch
* feature-branch
  main
```

##### **Step 3: Make Some Changes**

```plaintext
echo "New feature added!" > feature.txt
```

##### **Step 4: Stage the Changes**

```plaintext
git add feature.txt
```

##### **Step 5: Commit the Changes**

```plaintext
git commit -m "Added feature.txt with new feature"
```

##### **Step 6: Push the New Branch to GitHub**

```plaintext
git push origin feature-branch
```

### ***Challenge 3****:* ***Merge*** `feature-branch` ***into*** `main` ***and push the changes.***

##### **Step 1: Switch to the main Branch**

```plaintext
git checkout main
```

##### **Step 2: Ensure Your main Branch is Up-to-Date**

```plaintext
git pull origin main
```

**This fetches and merges the latest changes from the remote repository.**

##### **Step 3: Merge feature-branch into main**

```plaintext
git merge feature-branch
```

**If there are no conflicts, you’ll see:**

```plaintext
eks-auto-mode-workshop % git merge feature-branch
Updating cc73895..d1fec70
Fast-forward
 feature.txt | 1 +
 1 file changed, 1 insertion(+)
 create mode 100644 feature.txt
```

**If there are conflicts, Git will notify you, and you’ll need to manually resolve them.**

##### **Step 4: Push the Merged Changes to GitHub**

```plaintext
git push origin main
```

##### **Step 5: Delete feature-branch**

**After merging, you can delete the feature branch:**

```plaintext
MacBook-Pro eks-auto-mode-workshop % git branch -d feature-branch
Deleted branch feature-branch (was d1fec70).
MacBook-Pro eks-auto-mode-workshop % git push origin --delete feature-branch
To https://github.com/MusaveerHolalkere25/eks-auto-mode-workshop.git
 - [deleted]         feature-branch
```

### ***Challenge 4****:* ***Use*** `git reset` ***or*** `git revert` ***to undo a commit.***

##### **Using** `git reset:`

**Completely Remove the Last Commit**

```plaintext
git reset --hard HEAD~1
```

If you **want to undo the commit but keep the changes**:

```plaintext
git reset --soft HEAD~1
```

##### **Using** `git revert` **to Undo a Specific Commit Without Changing History**

```plaintext
git revert <commit-hash>
```

**Bonus** 💡 **If you've already pushed the commit to GitHub and need to force-push:**

```plaintext
git push origin main --force  # Use with caution!
```

### ***Challenge 5****:* ***Rebase*** `feature-branch` ***onto*** `main` ***and understand the difference.***

**First what is exactly a Git Rebase:**

`git rebase` is a command that moves or combines commits from one branch onto another, rewriting commit history in a linear way.

**Example:**

Before rebase (`git log --oneline --graph`):

```plaintext
* commit C (feature-branch)
* commit B (feature-branch)
| * commit M2 (main)
| * commit M1 (main)
|/
* commit A (common ancestor)
```

**After rebase:**

```plaintext
* commit C' (feature-branch, rebased)
* commit B' (feature-branch, rebased)
* commit M2 (main)
* commit M1 (main)
* commit A (common ancestor)
```

Now, to **rebase** `feature-branch` onto `main` using the following steps:

**Step 1: Switch to feature-branch**

`git checkout feature-branch`

**Step 2: Rebase feature-branch onto main**

**git rebase main**

**Explanation:**

* This **moves** feature-branch to start from the latest main commit.
    
* It applies feature-branch commits on top of main.
    

**Step 3: Resolve Any Merge Conflicts**

**If conflicts occur:**

1. **Git will pause and show which files have conflicts.**
    
2. **Manually edit the conflicting files** to resolve them.
    
3. **Mark conflicts as resolved:**  
    `git add <resolved-file>`
    
4. **Continue the rebase:**  
    `git rebase --continue`
    
5. **If you want to abort the rebase:**  
    `git rebase --abort`
    

###  💡 **Difference: Rebase vs Merge**

| **Feature** | **Rebase** | **Merge** |
| --- | --- | --- |
| **History** | Creates a **clean linear** history | Keeps a **branching history** |
| **Commits** | Moves commits on top of the latest `main` | Merges `main` changes **with a merge commit** |
| **Conflicts** | Can require resolving multiple conflicts | Resolves conflicts once at merge |
| **Recommended When** | You want a **clean history** (before merging) | You need a **clear branch history** |

### ***Challenge 6****:* ***Create a PR on GitHub from a feature branch.***

**Step 1: Push the Feature Branch to GitHub**

If your feature branch isn't pushed yet, run:

```plaintext
git push origin feature-branch
```

**Step 2: Open GitHub and Navigate to the Repository**

* **Go to your GitHub repository**.
    
* **Click on the "Compare & pull request"** button (it appears after pushing the branch).
    
* **Click on the "New pull request"**
    
* ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1742401355943/e991938d-c095-4762-8a0d-ea563b558914.png align="center")
    

**Step 3: Fill in PR Details**

1. **Ensure the correct base and compare branches**:
    
    * **Base branch**: main
        
    * **Compare branch**: feature-branch
        
2. **Add a Title & Description** (e.g., "Added new feature for user authentication").
    
3. **Optional**: Assign reviewers, add labels, or link issues.
    
4. ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1742401513043/b678a5e5-10ab-4a9b-bbad-d80e4306abb9.png align="center")
    

**Step 4: Create the PR**

1. Click **"Create Pull Request"**.
    
2. Your PR is now open for review.
    

**Step 5: Merge the PR (After Approval)**

Once approved, merge the PR:

1. Click **"Merge pull request"**.
    
2. Select **"Squash and merge"** (optional for a clean history).
    
3. **Delete the feature branch** if no longer needed.
    
4. ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1742401633429/3802e4fc-d29a-4e38-9a2d-86068aa1b824.png align="center")
    

**Bonus** 💡 **: Create a PR Using GitHub CLI (Optional)**

```plaintext
gh pr create --base main --head feature-branch --title "New Feature" --body "Description of the feature"
```

### ***Challenge 7****:* ***Create conflicting changes in different branches and resolve them.***

**Step 1: Create a Repository (or Use an Existing One)**

If you don’t have a repository, create one:

```plaintext
git init conflict-demo
cd conflict-demo
echo "Hello, DevOps!" > file.txt
git add file.txt
git commit -m "Initial commit"
```

**Step 2: Create and Modify feature-branch**

```plaintext
git checkout -b feature-branch

echo "Feature branch change" > file.txt

git add file.txt

git commit -m "Modified file.txt in feature-branch"
```

**Step 3: Switch to main and Make a Conflicting Change**

```plaintext
git checkout main

echo "Main branch change" > file.txt

git add file.txt

git commit -m "Modified file.txt in main"
```

Now, file.txt has different content in main and feature-branch, causing a **merge conflict**.

**Step 4: Merge feature-branch into main**

```plaintext
git merge feature-branch
```

**You’ll see a conflicting message like:**

```plaintext
Auto-merging file.txt

CONFLICT (content): Merge conflict in file.txt

Automatic merge failed; fix conflicts and then commit the result.
```

**Step 5: Resolve the Conflict**

**Open file.txt, which will look like this:**

```plaintext


<<<<<<< HEAD
Main branch change

=======

Feature branch change

>>>>>>> feature-branch
```

**Manually edit the file** to keep the correct content.  
**Mark the conflict as resolved**:

```plaintext
git add file.txt
git commit -m "Resolved merge conflict in file.txt"
```

**Step 6: Push the Merged Changes**

```plaintext
git push origin main
```

### ***Challenge 8:*** `git stash` ***to save and restore uncommitted changes.***

**Step 1: Make Some Changes to a File**

```plaintext
echo "Uncommitted changes" >> file.txt
```

**Check the status using** `git status` command:

```plaintext
git status
#Output:
Changes not staged for commit:
modified:   file.txt
```

**Step 2: Stash Uncommitted Changes**

```plaintext
git stash
```

This **saves the changes** and reverts your working directory to the last committed state.

Check the status again using `git status` the command:

```plaintext
git status

Nothing to commit, working tree clean.
```

**Step 3: Restore the Stashed Changes**

**To restore the last stashed changes:**

```plaintext
git stash pop
```

OR if you want to **apply the changes but keep them in stash**:

```plaintext
git stash apply
```

**Step 4: List All Stashes**

If you have multiple stashes:

```plaintext
git stash list

stash@{0}: WIP on feature-branch: 123abc Modified file.txt

stash@{1}: WIP on main: 456def Added a new feature
```

**Step 5: Restore a Specific Stash**

If you want to apply a specific stash:

```plaintext
git stash apply stash@{1}
```

**Step 6: Delete a Stash**

**After restoring, if you no longer need the stash:**

```plaintext
git stash drop stash@{0}
```

To **clear all stashes**:

```plaintext
git stash clear
```

### ***Challenge 9****:* ***Add version tags to commits and push them.***

**Step 1: Check the Latest Commit**

To verify which commit you’re tagging:

```plaintext
git log --oneline --graph --decorate -n 5

a1b2c3d (HEAD -> main) Added feature X

e4f5g6h Fixed bug Y

i7j8k9l Initial commit
```

**Step 2: Create a Tag**

1. **Lightweight Tag (Basic, No Message)**
    
    `git tag v1.0.0`
    
2. **Annotated Tag (With Message)**  
    `git tag -a v1.0.0 -m "Release version 1.0.0"`
    

**Step 3: List Tags**

```plaintext
git tag

#output
v1.0.0

#To view details of an annotated tag:
git show v1.0.0
```

**Step 4: Push the Tag to GitHub**

```plaintext
git push origin v1.0.0
```

To push **all tags**:

```plaintext
git push --tags
```

**Step 5: Delete a Tag (If Needed)**

1. **Delete a Local Tag**  
    `git tag -d v1.0.0`
    
2. **Delete a Remote Tag**  
    `git push origin --delete v1.0.0`
    

**Bonus** 💡 **: Checkout a Specific Tag**

**To create a branch from a tag:**

```plaintext
git checkout -b release-1.0 v1.0.0
```

### ***Challenge 10****:* ***Use*** `git commit --amend` ***and*** `git rebase -i` ***to edit past commits.***

**Step 1: Modify a Tracked File**

```plaintext
echo "New change" >> file.txt
git add file.txt
```

**Step 2: Amend the Last Commit**

```plaintext
git commit --amend -m "Updated commit with new changes"
```

✅ This **modifies the last commit** instead of creating a new one.

**Step 3: Push the Amended Commit (If Already Pushed)**

If you already pushed the commit, **force push is required**:

```plaintext
git push origin main --force
```

🚨 **Use with caution, as it rewrites history!**

**Option 2: Edit Older Commits (git rebase -i)**

If you need to modify a commit that is **not the last one**, use interactive rebase.

**Step 1: List Recent Commits**

```plaintext
git log --oneline -n 5
```

**Example output:**

```plaintext
a1b2c3d (HEAD -> feature-branch) Added new feature

e4f5g6h Fixed API issue

i7j8k9l Updated documentation

m0n1o2p Initial commit
```

**Step 2: Start an Interactive Rebase**

To modify the last **3 commits**:

```plaintext
git rebase -i HEAD~3
```

**Step 3: Modify Commits:**

The editor will show

```plaintext
pick a1b2c3d Added new feature
pick e4f5g6h Fixed API issue
pick i7j8k9l Updated documentation
```

**Change pick to:**

```plaintext
reword a1b2c3d Added new feature
edit e4f5g6h Fixed API issue
pick i7j8k9l Updated documentation
```

**Save and close** the editor.

**Step 4: Edit the Selected Commits**

For `reword`, Git will prompt you to **edit the commit message**.

For `edit`, Git will pause the rebase:

1. **Modify the commit (if needed)** :  
    `echo "Extra fix" >> file.txt`
    
    `git add file.txt`
    
    `git commit --amend`
    
2. `Continue the rebase:`  
    `git rebase --continue`
    

**Step 5: Push the Edited Commits**

If you already pushed the commits, **force push is required**:

```plaintext
git push origin feature-branch --force
```

*In conclusion, the 60 Days DevOps Challenge: Day 3 provides a comprehensive guide to mastering essential Git and GitHub skills. By completing the tasks and challenges outlined, participants gain hands-on experience in version control, branching, merging, and collaboration on open-source projects. These skills are crucial for efficient software development and collaboration in modern DevOps environments. As participants progress through the challenges, they build a solid foundation in Git operations, enabling them to manage code changes effectively and contribute to projects with confidence.*
