Featured image of post My Experience with Git

My Experience with Git

Little things and utilities that I wish I had known right away

Introduction

Frequently used commands and explanations for them. I hope this will be as useful to someone else as it has been to me.

Main

Git has a built-in graphical interface

Gitk - a simple built-in graphical interface. I really like it for its precision and clarity. I try not to use any Git UI and do everything with commands, and this one works only in view mode.

Gitk Interface

  1. Commit tree with tags and branches
  2. Hash of the selected commit from the tree
  3. List of changed files in this commit
  4. Diff mode toggle
  5. The diff of the commit with its description at the top

On Manjaro, in addition to Git itself, you need to install tk for it to work. I don’t know how it works on other distributions.

1
pacman -Sy git tk

How to update environment settings based on the diff of the new environment

Here’s the thing. In my infrastructure repository, I have, for example, values for Helmfile environments Development and Production.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
.
├── development
   ├── main.yaml
   └── values
       ├── cert-manager.yaml.gotmpl
       ├── external-secrets.yaml.gotmpl
       ├── fluentbit.yaml.gotmpl
       ├── kube-prometheus-stack.yaml.gotmpl
       ├── loki.yaml.gotmpl
       └── promtail.yaml.gotmpl
└── production
    ├── main.yaml
    └── values
        ├── cert-manager.yaml.gotmpl
        ├── external-secrets.yaml.gotmpl
        ├── fluentbit.yaml.gotmpl
        ├── kube-prometheus-stack.yaml.gotmpl
        ├── loki.yaml.gotmpl
        └── promtail.yaml.gotmpl

5 directories, 14 files

So I was developing new applications, changing settings in development, and now I need to transfer all the same to production. To avoid recalling all the little things that need to be changed, I do the following.

  1. Switch to the branch with the current development
1
git checkout development
  1. Check when production was last changed
1
git log -n 1 --oneline -- ./production

Here, ./production is the path to the folder we are interested in for file changes. You can specify a specific file or multiple sources. In this case, we will get the hash of the last commit that made any changes in production.

  1. Check the changes from that moment to the present

Now we need to track all changes from the last version of production to the current moment, which is the current development.

1
git diff 493d3aa..HEAD -- ./development

The hash 493d3aa is the one I obtained in the previous point for production.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
diff --git a/development/values/cert-manager.yaml.gotmpl b/development/values/cert-manager.yaml.gotmpl
index 493d3aa..cb34bd2 100644
--- a/development/values/cert-manager.yaml.gotmpl
+++ b/development/values/cert-manager.yaml.gotmpl
@@ -34,7 +34,8 @@ asdf:
     alpha: cert-manager-a
   contextKey:
     beta: something-else
-    key: json
+  someSetting:
+    subkey: cert-manager-example
   urls:
     api: {{ quote .Values.apiURL }}
     web: {{ quote .Values.webURL }}

Thus, we can now manually transfer all the changes we are interested in to production without losing anything.

Git has a built-in search for files in commits. You can use regular expressions to search for secret data. This is applicable in individual manual operations, but it would be much better to set up and constantly use Gitleaks or Trivy.

1
2
git rev-list --all | \
xargs git grep -irnE '"type":\s*"service_account"'

Search results for the substring “val”

This way, you can find all files in history that contain secrets and perform rotation. It doesn’t make sense to cut them out of history; it’s better just to change the secrets.

Rebase strategies

When you need to perform a rebase with a lot of conflicts and you know that you simply need to keep everything as it is in the current/target branch, you can do the following.

  1. Make sure that our local branch (which we will be rebasing) is pushed and is the same as in the cloud.

Why is this necessary? For self-control. For example, I have a task to rebase the development branch onto main without changing it, just moving it. If at the start of the transfer I checked that there was no diff for origin/development, then after the transfer, I can compare git diff origin/development..development, and it should also be empty.

1
2
git pull
git push
  1. Perform one of the operations below
1
2
git rebase -i --strategy=ort -Xtheirs main --empty=keep
git rebase -i --strategy=ort -Xours main --empty=keep

Git will resolve all conflicts in favor of one of the branches, depending on ours or theirs.

How to reset a local branch to the state of the cloud if someone pushed with force

This is quite simple. For example, we are working on development.

  1. Switch to the branch
1
git checkout development
  1. Perform git fetch
1
git fetch --all
  1. Perform a reset
1
git reset --hard origin/development

That’s it; our branch is now exactly as it is in the cloud.

Licensed under Apache License, Version 2.0
Last updated on Dec 10, 2024 14:01 +0200
All rights reserved
Built with Hugo
Theme Stack designed by Jimmy