Advance Git & GitHub for DevOps Engineers: Part-2

Git Stash: If you are working on a file which is in the staging area (not committed yet) and for some reason you need to switch to another branch by using the "git checkout <branch name>" command, Git will give you 2 options to proceed with: commit, & stash. We know by now what commit does, however, let's have a look at "git stash". "git stash" command allows you to switch to another branch without committing to your current branch and it saves your work temporarily in a "stash". Stash is a temporary commit that's not part of the Git history.

To apply the changes from stash, you can use the "git stash pop" command which will bring up the most recent stash and you can continue to work and eventually make your commit. If you wish to discard the stashed file, you can use the "git stash drop" command. If you wish to discard all stashed files, you can use the "git stash clear" command. See Task 1 below with an example of the "git stash" & "git stash pop" commands being used.

Git Stash image - https://www.youtube.com/watch?v=wpHEjqIjJGQ

Cherry-Pick: It's the process of picking up a particular commit and applying them to another branch as if you had made those changes on the other branch yourself. The head now applies to the latest commit in your version control system.

In the code example, I was in the dev branch to start with. I made a change in the "feature2.txt" file and wanted to put that in the master. Rather than using Git Merge (if "git merge" is used, then other features after 2 will be added as well which I don't want), I used the "git cherry-pick" command with the commit ID (2ee09e8) for the feature. This way the result is that my "feature2.txt" file with the update now is in the master branch. If you run the "cat" command for the "feature2.txt" file now in the master branch, you can see the changes which were made in the dev branch appearing in the master branch.

ubuntu@ip-172-31-92-141:~/devops-batch-3$ cat feature2.txt
this is a another new feature
ubuntu@ip-172-31-92-141:~/devops-batch-3$ vim feature2.txt
ubuntu@ip-172-31-92-141:~/devops-batch-3$ git status
On branch dev
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:   feature2.txt

no changes added to commit (use "git add" and/or "git commit -a")
ubuntu@ip-172-31-92-141:~/devops-batch-3$ git add feature2.txt
ubuntu@ip-172-31-92-141:~/devops-batch-3$ git commit -m "added feature 2 changes"
[dev 2ee09e8] added feature 2 changes
 1 file changed, 2 insertions(+)
ubuntu@ip-172-31-92-141:~/devops-batch-3$ git log --oneline
2ee09e8 (HEAD -> dev) added feature 2 changes
14ea635 feature 3 file now has been fixed
8f85e77 added new feature by developer
ac1eecb (master) added new feature
c28b1b3 added first feature
ubuntu@ip-172-31-92-141:~/devops-batch-3$ git checkout master
Switched to branch 'master'
ubuntu@ip-172-31-92-141:~/devops-batch-3$ git cherry-pick 2ee09e8
[master 105d0e9] added feature 2 changes
 Date: Fri Apr 28 04:40:42 2023 +0000
 1 file changed, 2 insertions(+)
ubuntu@ip-172-31-92-141:~/devops-batch-3$ ls
feature1.txt  feature2.txt
ubuntu@ip-172-31-92-141:~/devops-batch-3$ git branch
  dev
* master
ubuntu@ip-172-31-92-141:~/devops-batch-3$ cat feature2.txt
this is a another new feature

Developer 2 added some changes to this feature!
ubuntu@ip-172-31-92-141:~/devops-batch-3$

Resolving Conflict: Merge conflicts in Git happens when you are attempting to merge the two branches. Git will not be able to merge them, so the developer will need to resolve these conflicts manually. Let's have a look at this scenario which we discussed in class about how a change of code was made on the local file which was different than what was on the remote repo and the steps we took to resolve this conflict. There was a new file added "feature4.txt" and it was committed. "git pull origin dev" command was used to pull from the remote repo and some messages were given by Git that we have divergent branches and needed to specify how to reconcile the divergent branches. We had 2 options: rebase or review to see the correct code to fix. Rebase option was used via the command "git pull origin dev --rebase". A message by Git stated to resolve all conflicts manually and mark them to be resolved. Opened the "feature4.txt" local file via Vim Editor which displayed what was pointing at the head and what was pointing at the local repo. It was decided to go with the local repo code. In this case, you delete the code which is pointing at the head and replace it with your local code deleting the forward and backward arrows. See below the Bash code for the before and after images of manually resolving the conflict.

Once the file is saved, you can use the "git status" command which should show you both the modified & suggest to fix the conflict. "git rebase --continue" command was used which prompted to edit all merge conflicts and that mark them as resolved using "git add". "git add" command was used and followed by "git rebase --continue" command which opened up the Nano Editor where comments were added about resolving the conflict. Save and close the Nano Editor. As you can see the conflict is resolved and you have successfully rebased as well.

ubuntu@ip-172-31-92-141:~/devops-batch-3$ ls
README.md  feature1.txt  feature2.txt  feature3.txt  feature4.txt
ubuntu@ip-172-31-92-141:~/devops-batch-3$ vim feature4.txt
ubuntu@ip-172-31-92-141:~/devops-batch-3$ git add feature4.txt
ubuntu@ip-172-31-92-141:~/devops-batch-3$ git commit -m "added a new feature by dev1"
[dev 7e8c4f6] added a new feature by dev1
 1 file changed, 2 insertions(+)
ubuntu@ip-172-31-92-141:~/devops-batch-3$ git pull origin dev
remote: Enumerating objects: 5, done.
remote: Counting objects: 100% (5/5), done.
remote: Compressing objects: 100% (3/3), done.
remote: Total 3 (delta 1), reused 0 (delta 0), pack-reused 0
Unpacking objects: 100% (3/3), 691 bytes | 691.00 KiB/s, done.
From https://github.com/samsamarullah/devops-batch-3
 * branch            dev        -> FETCH_HEAD
   ba2ddf1..48ca450  dev        -> origin/dev
hint: You have divergent branches and need to specify how to reconcile them.
hint: You can do so by running one of the following commands sometime before
hint: your next pull:
hint: 
hint:   git config pull.rebase false  # merge (the default strategy)
hint:   git config pull.rebase true   # rebase
hint:   git config pull.ff only       # fast-forward only
hint: 
hint: You can replace "git config" with "git config --global" to set a default
hint: preference for all repositories. You can also pass --rebase, --no-rebase,
hint: or --ff-only on the command line to override the configured default per
hint: invocation.
fatal: Need to specify how to reconcile divergent branches.
ubuntu@ip-172-31-92-141:~/devops-batch-3$ git push origin dev
To https://github.com/samsamarullah/devops-batch-3.git
 ! [rejected]        dev -> dev (non-fast-forward)
error: failed to push some refs to 'https://github.com/samsamarullah/devops-batch-3.git'
hint: Updates were rejected because the tip of your current branch is behind
hint: its remote counterpart. Integrate the remote changes (e.g.
hint: 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.
ubuntu@ip-172-31-92-141:~/devops-batch-3$ git pull origin dev --rebase
From https://github.com/samsamarullah/devops-batch-3
 * branch            dev        -> FETCH_HEAD
Auto-merging feature4.txt
CONFLICT (content): Merge conflict in feature4.txt
error: could not apply 7e8c4f6... added a new feature by dev1
hint: Resolve all conflicts manually, mark them as resolved with
hint: "git add/rm <conflicted_files>", then run "git rebase --continue".
hint: You can instead skip this commit: run "git rebase --skip".
hint: To abort and get back to the state before "git rebase", run "git rebase --abort".
Could not apply 7e8c4f6... added a new feature by dev1
ubuntu@ip-172-31-92-141:~/devops-batch-3$ vim feature4.txt
ubuntu@ip-172-31-92-141:~/devops-batch-3$ git status
interactive rebase in progress; onto 48ca450
Last command done (1 command done):
   pick 7e8c4f6 added a new feature by dev1
No commands remaining.
You are currently rebasing branch 'dev' on '48ca450'.
  (fix conflicts and then run "git rebase --continue")
  (use "git rebase --skip" to skip this patch)
  (use "git rebase --abort" to check out the original branch)

Unmerged paths:
  (use "git restore --staged <file>..." to unstage)
  (use "git add <file>..." to mark resolution)
    both modified:   feature4.txt

no changes added to commit (use "git add" and/or "git commit -a")
ubuntu@ip-172-31-92-141:~/devops-batch-3$ git rebase --continue
feature4.txt: needs merge
You must edit all merge conflicts and then
mark them as resolved using git add
ubuntu@ip-172-31-92-141:~/devops-batch-3$ git add feature4.txt
ubuntu@ip-172-31-92-141:~/devops-batch-3$ git status
interactive rebase in progress; onto 48ca450
Last command done (1 command done):
   pick 7e8c4f6 added a new feature by dev1
No commands remaining.
You are currently rebasing branch 'dev' on '48ca450'.
  (all conflicts fixed: run "git rebase --continue")

Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
    modified:   feature4.txt

ubuntu@ip-172-31-92-141:~/devops-batch-3$ git rebase --continue
[detached HEAD 6ce0fea] added a new feature by dev1 resolved the conflict.
 1 file changed, 1 insertion(+), 1 deletion(-)
Successfully rebased and updated refs/heads/dev.
ubuntu@ip-172-31-92-141:~/devops-batch-3$

The above was a specific scenario which was demonstrated. However, the steps in general to resolve merge conflicts are:

  1. First, ensure that you have committed all changes on your current branch. You can check the status of your branch using the "git status" command.

  2. Next, switch to the branch you want to merge into your current branch using the "git checkout" command. For example, if you want to merge the "feature-branch" into your current branch, you would run "git checkout your-current-branch" followed by "git merge feature-branch".

  3. Git will try to automatically merge the changes from the two branches. If it encounters a conflict, it will pause the merge and provide you with a message explaining the conflict.

  4. To resolve the conflict, open the file(s) that contain the conflict(s) in your preferred text editor. The conflicting lines will be marked with Git's conflict markers "<<<<<<<", "\=======", and "\>>>>>>>".

  5. Edit the file to remove the conflict markers and manually merge the conflicting changes. You can choose to keep one version of the change or merge the changes together manually. Be sure to remove all conflict markers from the file once you have resolved the conflict.

  6. Once you have resolved all conflicts, save the file(s) and run "git add" to stage the changes.

  7. Finally, run "git commit" to create a new commit with the resolved merge conflicts. Git will automatically close the merge and complete the process.

Always keep in mind to communicate all conflicts or issues with your team so they are aware.


Task 1

  • Create a new branch and make some changes to it.

  • Use git stash to save the changes without committing them.

  • Switch to a different branch, make some changes and commit them.

  • Use git stash pop to bring the changes back and apply them on top of the new commits.

I created a new branch name "feature/log-out" and added a file name "test_file1.txt". I used the "git add" command which added a change in the working directory to the staging area. I used the "git stash" command to make my temporary change. I switched over to the dev branch to work on another file. Once completed, I used the "git stash list" to see the stashes. I used the "git stash pop" command to bring the changes back and apply them on top of the new commits. See the code below.

ubuntu@ip-172-31-92-141:~/devops-batch-3$ git checkout -b feature/log-out
Switched to a new branch 'feature/log-out'
ubuntu@ip-172-31-92-141:~/devops-batch-3$ vim test_file1.txt
ubuntu@ip-172-31-92-141:~/devops-batch-3$ cat test_file.txt
cat: test_file.txt: No such file or directory
ubuntu@ip-172-31-92-141:~/devops-batch-3$ cat test_file1.txt
test file created`
ubuntu@ip-172-31-92-141:~/devops-batch-3$ git add .
ubuntu@ip-172-31-92-141:~/devops-batch-3$ git stash
Saved working directory and index state WIP on log-out: c6bcc68 feature 4 added
ubuntu@ip-172-31-92-141:~/devops-batch-3$ git checkout dev
Switched to branch 'dev'
ubuntu@ip-172-31-92-141:~/devops-batch-3$ ls
README.md  blank_file.txt  feature1.txt  feature2.txt  feature3.txt  feature4.txt
ubuntu@ip-172-31-92-141:~/devops-batch-3$ touch testing_feature5.txt
ubuntu@ip-172-31-92-141:~/devops-batch-3$ git add .
ubuntu@ip-172-31-92-141:~/devops-batch-3$ git commit -m "added a testing_feature5 file"
[dev 6c07a86] added a testing_feature5 file
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 testing_feature5.txt
ubuntu@ip-172-31-92-141:~/devops-batch-3$ git stash list
stash@{0}: WIP on log-out: c6bcc68 feature 4 added
stash@{1}: WIP on contact-page: 5f0e193 added dev1 changes to the code
stash@{2}: WIP on contact-page: 5f0e193 added dev1 changes to the code
ubuntu@ip-172-31-92-141:~/devops-batch-3$ git stash pop
On branch dev
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
    new file:   test_file1.txt

Dropped refs/stash@{0} (fae7f818dec0191d1e5865d148a2e3cff0e45934)
ubuntu@ip-172-31-92-141:~/devops-batch-3$ git add .
ubuntu@ip-172-31-92-141:~/devops-batch-3$ git commit -m "test_file1.txt being commited now from stash"
[dev 073d09d] test_file1.txt being commited now from stash
 1 file changed, 1 insertion(+)
 create mode 100644 test_file1.txt
ubuntu@ip-172-31-92-141:~/devops-batch-3$ git log --oneline
073d09d (HEAD -> dev) test_file1.txt being commited now from stash
6c07a86 added a testing_feature5 file
c6bcc68 (feature/log-out) feature 4 added
b90c119 added a blank file
6ce0fea added a new feature by dev1 resolved the conflict.
48ca450 (origin/dev) Update feature4.txt
ba2ddf1 Update feature4.txt
cff9a14 Merge pull request #1 from samsamarullah/feature/new-test
d50f5ad (origin/feature/new-test) added new feature 4 by dev 2
5f0e193 (master, feature/contact-page) added dev1 changes to the code
93bcc60 feature 3 file now has been fixed
9f7d3ca added new feature by developer
4448480 added feature 2 changes
8301df5 added new feature
2d35914 added first feature
a625fbf (origin/main) Initial commit
ubuntu@ip-172-31-92-141:~/devops-batch-3$

Task 2

  • In version01.txt of the development branch add the below lines after “This is the bug fix in development branch” that you added in your previous blog and revert it to this commit.

  • Line2>> After bug fixing, this is the new feature with minor alterations”

    Commit this with the message “ Added feature2.1 in development branch”

  • Line3>> This is the advancement of the previous feature

    Commit this with the message “ Added feature2.2 in development branch”

  • Line4>> Feature 2 is completed and ready for release

    Commit this with the message “ Feature2 completed”

  • All these commits messages should be reflected in the Production branch too which will come out from the Master branch.

ubuntu@ip-172-31-92-141:~/devops/git$ git checkout dev
Switched to branch 'dev'
ubuntu@ip-172-31-92-141:~/devops/git$ ls
version01.txt
ubuntu@ip-172-31-92-141:~/devops/git$ vim version01.txt
ubuntu@ip-172-31-92-141:~/devops/git$ cat version01.txt
This is the 1st feature of our application.

This is the bug fix in the dev branch

After bug fixing, this is the new feature with minor alterations.


ubuntu@ip-172-31-92-141:~/devops/git$ git add .
ubuntu@ip-172-31-92-141:~/devops/git$ git commit -m "Added feature2.1 in the dev branch"
[dev 00ba914] Added feature2.1 in the dev branch
 1 file changed, 2 insertions(+)
ubuntu@ip-172-31-92-141:~/devops/git$ vim version01.txt
ubuntu@ip-172-31-92-141:~/devops/git$ git add .
ubuntu@ip-172-31-92-141:~/devops/git$ git commit -m "Added feature2.2 in the dev branch"
[dev 7cd59d7] Added feature2.2 in the dev branch
 1 file changed, 2 insertions(+)
ubuntu@ip-172-31-92-141:~/devops/git$ vim version01.txt
ubuntu@ip-172-31-92-141:~/devops/git$ git add .
ubuntu@ip-172-31-92-141:~/devops/git$ git commit -m "Feature 2 completed"
[dev 01f3f29] Feature 2 completed
 1 file changed, 3 insertions(+)
ubuntu@ip-172-31-92-141:~/devops/git$ git branch
* dev
  hotfix
  master
  test_qa
ubuntu@ip-172-31-92-141:~/devops/git$ git checkout -b production
Switched to a new branch 'production'
ubuntu@ip-172-31-92-141:~/devops/git$ git rebase dev
Current branch production is up to date.
ubuntu@ip-172-31-92-141:~/devops/git$ ls
version01.txt
ubuntu@ip-172-31-92-141:~/devops/git$ cat version01.txt
This is the 1st feature of our application.

This is the bug fix in the dev branch

After bug fixing, this is the new feature with minor alterations.

This is the advancement of the previous feature.

Feature 2 is completed and ready for release.

ubuntu@ip-172-31-92-141:~/devops/git$ git log --oneline
01f3f29 (HEAD -> production, dev) Feature 2 completed
7cd59d7 Added feature2.2 in the dev branch
00ba914 Added feature2.1 in the dev branch
eee105a (master) Revert "Added feature 3 in the dev branch"
f634261 Revert "Added feature 4 in the dev branch"
47301ff Added feature 4 in the dev branch
a6dcbe5 Added feature 3 in the dev branch
22854af Added feature 2 in the dev branch
f81d9f9 (origin/dev, test_qa, hotfix) This commit is for our 1st feature of our app
ubuntu@ip-172-31-92-141:~/devops/git$

Task 3

  • In the Production branch Cherry pick Commit “Added feature2.2 in development branch” and add the below lines in it:

  • The line to be added after Line3>> This is the advancement of the previous feature

  • Line 4>>Added a few more changes to make it more optimized.

  • Commit: Optimized the feature

ubuntu@ip-172-31-92-141:~/devops/git$ git log --oneline
01f3f29 (HEAD -> production, dev) Feature 2 completed
7cd59d7 Added feature2.2 in the dev branch
00ba914 Added feature2.1 in the dev branch
eee105a (master) Revert "Added feature 3 in the dev branch"
f634261 Revert "Added feature 4 in the dev branch"
47301ff Added feature 4 in the dev branch
a6dcbe5 Added feature 3 in the dev branch
22854af Added feature 2 in the dev branch
f81d9f9 (origin/dev, test_qa, hotfix) This commit is for our 1st feature of our app
ubuntu@ip-172-31-92-141:~/devops/git$ git checrry-pick 7cd59d7
git: 'checrry-pick' is not a git command. See 'git --help'.

The most similar command is
    cherry-pick
ubuntu@ip-172-31-92-141:~/devops/git$ git cherry-pick 7cd59d7
Auto-merging version01.txt
CONFLICT (content): Merge conflict in version01.txt
error: could not apply 7cd59d7... Added feature2.2 in the dev branch
hint: After resolving the conflicts, mark them with
hint: "git add/rm <pathspec>", then run
hint: "git cherry-pick --continue".
hint: You can instead skip this commit with "git cherry-pick --skip".
hint: To abort and get back to the state before "git cherry-pick",
hint: run "git cherry-pick --abort".
ubuntu@ip-172-31-92-141:~/devops/git$ vim version01.txt
ubuntu@ip-172-31-92-141:~/devops/git$ git add version01.txt
ubuntu@ip-172-31-92-141:~/devops/git$ git commit -m "optimized the feature"
[production e26c5cc] optimized the feature
 Date: Thu May 4 17:13:16 2023 +0000
 1 file changed, 1 insertion(+), 3 deletions(-)
ubuntu@ip-172-31-92-141:~/devops/git$ git status
On branch production
nothing to commit, working tree clean
ubuntu@ip-172-31-92-141:~/devops/git$ git log --oneline
e26c5cc (HEAD -> production) optimized the feature
01f3f29 (dev) Feature 2 completed
7cd59d7 Added feature2.2 in the dev branch
00ba914 Added feature2.1 in the dev branch
eee105a (master) Revert "Added feature 3 in the dev branch"
f634261 Revert "Added feature 4 in the dev branch"
47301ff Added feature 4 in the dev branch
a6dcbe5 Added feature 3 in the dev branch
22854af Added feature 2 in the dev branch
f81d9f9 (origin/dev, test_qa, hotfix) This commit is for our 1st feature of our app
ubuntu@ip-172-31-92-141:~/devops/git$

I appreciate your busy time reading this short blog. As I continue with my journey to learn and acquire the skill set of a DevOps Engineer, I will share what I learn. Thank you.

Happy Learning!


Sam Samarullah

LinkedIn

Previous Blog

#git #github #devops #devopstools #devopsworld