Category: Git

Squash two commits into one

Is it possible that you can’t use the visual squash commit with Github Desktop:

If the two commits is one before the other, so you can use the following command to take the 2 last commits :

git rebase -i HEAD~2

This will show the VI text editor, and you will have to change the text “pick” to “squash” for the last commit and only the last one because you only want the last to be squashed into the other one.
So, when you do this command, you will see something like:

pick abc1234567 Commit message for commit1
pick def1234567 Commit message for commit2

Change the second “pick” to “squash” :

pick abc1234567 Commit message for commit1
squash def1234567 Commit message for commit2

In VI editor, save it by pressing escape then: :x!
Do it another time if you can see another editor.
Check it with git log or Git Desktop

You can then force push to apply the changes and the remote repository.

git push --force

Squash several commits into one

To squash several commits, first you should know how many commits you want to squash.
If it is 15 commits, you should then you the following command:

git rebase -i HEAD~15

In the VI editor to search and replace “pick” to “squash” (with question that ask if you want to replace) use:
Press escape and then: :2,$s/pick/squash/c
⚠️ You should not replace the first one, the first one will still “pick”.
Then save it by pressing escape then: :x!

Here is an example, I did the rebase :

pick ab12345678 feat: important feature
pick cd12345678 feat: important feature to squash
pick ef12345678 feat: important feature to squash
pick gh12345678 feat: important feature to squash

Then I replace all the “pick” except the first one:

pick ab12345678 feat: important feature
squash cd12345678 feat: important feature to squash
squash ef12345678 feat: important feature to squash
squash gh12345678 feat: important feature to squash
 
# Rebase ab12345678..cd12345678 onto ef12345678 (2 commands)
#
# Commands:
# p, pick <commit> = use commit
# r, reword <commit> = use commit, but edit the commit message
# e, edit <commit> = use commit, but stop for amending
# s, squash <commit> = use commit, but meld into previous commit
# f, fixup [-C | -c] <commit> = like "squash" but keep only the previous
#                    commit's log message, unless -C is used, in which case
#                    keep only this commit's message; -c is same as -C but
#                    opens the editor
# x, exec <command> = run command (the rest of the line) using shell
# b, break = stop here (continue rebase later with 'git rebase --continue')
# d, drop <commit> = remove commit
:x!

Rename git branch

Use git command line (with git bash on Windows) to change the branch name.

1 – Be sure you are on the right branch

Firstly, you should be on your current branch (the branch you want to rename) with git checkout.

2 – Change the name of the branch locally

Secondly, you should rename the branch with the following command:

git branch -m <the_new_branch_name>

The new branch name should be valid, with no space. If you use special characters you should use quotes like:

git branch -m “let’s-put-a-complicated-name”

3 – Change the name of the branch remotely

You can now change the name of the branch remotely so it’s also changed on github / gitlab / bitbucket etc.
To do push it use:

git push origin HEAD:<old_branch_name>

If it’s a complicated name you can still use the quotes:
git push origin HEAD:”it’s-an-old-branch-name”

Git : Don’t commit node_modules except a file in a library

If you are using the node_modules in your Node.JS / Javascript / Typescript project you should exclude to commit all the libraries used by your application with this line in the .gitignore file:

.gitignore

node_modules/

But, you may need to modify a file in the /node_modules folder, excluded in the .gitignore

Force commit a file in a excluded folder in .gitignore

If you want to fix a file in a library that makes some problems in your application, you may want to modify the library directly in /node_modules (the case you are using the last version of the library, you can check on https://www.npmjs.com/ if you are using the last version in your package.json)

In my case, I modified node_modules/react-native-firebase/ios/RNFirebase/notifications/RNFirebaseNotifications.m a library that is not changed since 2 years and have a problem in my application. You can of course make a git issue on the official page but if you need it to work fast, you may want to commit it directly in your project and it is fixed.

After you made the change in the library, you can commit with git add -f …

In my case:

git add -f node_modules/react-native-firebase/ios/RNFirebase/notifications/RNFirebaseNotifications.m
You can see your file to be commit in your Git Desktop, and my node_modules folder is excluded in .gitignore

How to remove git token on git project after a failed git pull

After doing a git pull is it possible you have an error because your Git Token is not valid anymore, here is an exemple:

# git pull
remote: HTTP Basic: Access denied
fatal: Authentication failed for 'https://gitlab-ci-token:YOURTOKEN@gitlab.com/YOURPROJECT.git/'

In order to do the git pull we want to use our credential with the LOGIN / PASSWORD that we use to access GitLab.

Solution 1 : Git pull one time with login (temporary)

# git pull https://gitlab.com/YOURPROJECT.git

Solution 2 : Change the origin URL to HTTPS (permanent)

# git remote set-url origin https://gitlab.com/YOURPROJECT.git
# git pull

It will ask your login and password for the git pull and will not use the git token anymore.

Git commands on production server & Git issues

The following commands can be used on a production server.
In the case of a local machine development, use free software like GIT DESKTOP / SourceTree

First deployment in a folder

git clone <URL GITLAB/GITHUB HTTPS>

Updating / Getting last changes

git pull

The following commands respond to particular problems that may arise.

Changing the URL of a GIT Repository

This problem can occur if you are using GITLAB or GITHUB with SSH and you want to switch to HTTPS or vice versa, or following problems with the rights of an SSH key such as “remote: The project you were looking for could not be found.” and “fatal: Could not read from remote repository.”

Checking the repository URL:

git remote -v

Changing the URL of the repository:

git remote set-url origin <URL>

You cannot pull the changes “You have unstaged changes”

You may get the following error, indicating that some files have changed and need to be committed when you haven’t touched anything and just want to update the server:

Cannot pull with rebase: You have unstaged changes. 
Please commit or stash them. 

In order the solve this problem we should remove all the unstaged changes:

git reset --hard

You can now use the git pull command.

Back to the previous commit

git reset --hard HEAD^

Back to a specific commit

git reset --hard <ID COMMIT>

The commit ID is usually 7 digits and hexadecimal letters, example:
26b47fa

You can find it in the history tab of your GIT DESKTOP

Deleting a Commit in the Middle of the History

The two previous commands can delete commits but they are removing from the begining (the most recents commits). It is possible that we want for example to keep the most recent commit and delete a commit in the middle of the history. Replace “sha1-commit-hash” with the ID of the commit BEFORE the first commit you want to delete. For example, if you want to delete the 2nd, 3rd commit in a chronological order, then put the ID of the 4th commit, in a way to see the 3 commits in the editor.

git rebase -i <sha1-commit-hash>

This will open the editor. On the line of the commit you want to remove, change the text “pick” to “drop“.

drop ab12345678 feat: feature to delete # empty
pick cd12345678 feat: important feature

# Rebase ab12345678..cd12345678 onto ef12345678 (2 commands)
#
# Commands:
# p, pick <commit> = use commit
# r, reword <commit> = use commit, but edit the commit message
# e, edit <commit> = use commit, but stop for amending
# s, squash <commit> = use commit, but meld into previous commit
# f, fixup [-C | -c] <commit> = like "squash" but keep only the previous
#                    commit's log message, unless -C is used, in which case
#                    keep only this commit's message; -c is same as -C but
#                    opens the editor
# x, exec <command> = run command (the rest of the line) using shell
# b, break = stop here (continue rebase later with 'git rebase --continue')
# d, drop <commit> = remove commit
:x!

Use :x! to save your modifications and then check it in Git Desktop history or git log command.

Tips: if you have several commits to delete, you can use 2,$s/pick/drop/c to replace (it will ask if you want to replace with “Y” yes or “N” no)

Then you can git push –force to push it on the remote repository.


Overwrite changes on the distant repository (local > remote)

git push --force origin master

Caution, delete on the distant repository, useful if you want to “delete” a commit that has been pushed.

Overwrite changes on the local repository (remote > local)

git reset --hard origin/master

Caution, deletes all the changes made not pushed to the remote git, useful if you want to “delete” the commits locally to have the same thing as on the remote git.

Compare different branches with GitLens

Is it possible that in your working project, you are using different branch that you need to update and you cannot merge in master because of some obligations (working with different clients, different teams, …). So what we want is only to update few files when we modify it on another branch.

I find out an amazing tool GitLens to compare different branches from your git project directly from the IDE (using Visual Studio Code).

You can find it in the Marketplace here is what it looks like:

After you have installed it, you will have a new tab on Visual Studio Code, in this tab you will be able to see 5 tools:

  • Repositories : See on which repositories and branch you are working on
  • Files History : visualize navigate and explore the revision history of current file
  • Line History : visualize navigate and explore the history of the selected lines of current file
  • Compare Commits : to visualize comparisons between branches, tags, commits, and more, THIS is the most interesting tool that we are going to use
  • Search Commits : to search and explore commit histories

With the Compare Commits tool we can click Compare <branch, tag, or ref> and be able to compare 2 branch:

VinceOPS | Git : Astuces et productivité #2

If you click on a commit or a file, you will be in read only mode. To modify your file side by side you will have to click on a button.
This button is Compare with HEAD here is where is it located:

You can now compare and modify the file side by side, what you cannot do with Visual Studio in a single branch.

Commandes GIT sur serveur en production

Les commandes suivantes peuvent être utilisé sur un serveur en production.
Dans le cas d’un déveleppement sur machine locale, utiliser des logiciels gratuits comme GIT DESKTOP / SourceTree.

Voici les deux commandes utilisés au quotidien:

Premier déploiement dans un dossier

git clone <URL GITLAB/GITHUB HTTPS>

Mise à jour / Récupération des derniers changements

git pull

Les commandes suivantes répondent à des problematiques particulières qui peuvent arriver.

Changement de l’URL du repository GIT

Ce problème peut intervenir notamment si vous utilisez GITLAB ou GITHUB en SSH et que vous voulez passer en HTTPS ou vis versa, ou suite à des problèmes de droits d’une clé SSH type “remote: The project you were looking for could not be found.” et “fatal: Could not read from remote repository.”

Vérification de l’URL du repository:

git remote -v

Changement de cet URL:

git remote set-url origin <URL>

Changement de branche

git checkout <nom_de_la_branche>

Le git pull ne fonctionne pas “You have unstaged changes”

Il se peut que vous ayez l’erreur suivante, indiquant que des fichiers ont changés et doivent être commit alors que vous n’avez rien touché et que vous souhaitez juste mettre le serveur à jour :

Cannot pull with rebase: You have unstaged changes. 
Please commit or stash them. 

Dans ce cas, on doit supprimer ces changements avec la commande suivante :

git reset --hard

Vous pouvez ensuite faire votre git pull

Revenir au commit précédent

git reset --hard HEAD^

Revenir à un commit précis

git reset --hard <ID COMMIT>

L’ID du commit est générallement à 7 chiffres et lettres hexadecimal, exemple:
26b47fa

Vous pouvez le trouver dans l’onglet historique de votre GIT DESKTOP

Ecraser les modifications sur le repository distant (local > remote)

git push --force origin master

Attention, écrase le répository distant, utile si vous voulez “supprimer” un commit qui a été pushé.

Ecraser les modifications sur le repository local (remote > local)

git reset --hard origin/master

Attention, supprime toutes les modifications faites non pushé vers le git distant, utile si vous voulez “supprimer” les commits en local pour avoir la même chose que sur le git distant.