ikriv.com

A year of using Git: the good, the bad, and the ugly

2/24/2012Updated 1/5/2026

Excerpt

Here is my take on the good, the bad, and the ugly sides of Git. **GOOD**: great performance, full local source control that works even when disconnected from the server, ability to move work quickly between servers without losing history. **BAD**: complexity of workflow, more entities to keep track of, lots of new confusing terms, “one repo is one project” policy, limited/outdated information about the remote, misleading messages. Commit labels are not integers, which complicates build/version number generation. … ### Complexity of Workflow Simply put, with Git you need more steps to move your work to the server, even in simple cases. With traditional source control systems you record the changes using the “commit” command. With Git you also need to “push” your work to origin, which is easy to forget. This is not a theoretical concern: every developer in my team, myself included, had cases when they forgot to push the code to origin. You commit locally, you get distracted, and voila: your colleague comes to you with “I pulled the latest, but I can’t see your changes!”. Unlike SVN, Git requires you to explicitly specify which modified files you want to check in. Fortunately, this is a problem only for strict command line environments. Most tools automate the task of finding modified files and adding them to “the index” before check in. If you use branches and tags heavily, the situation is even worse. Each branch and tag must be created twice: in the local world and in the remote world, or they will be visible only to you. It is not easy to check which branches were pushed to origin, and tags are not pushed to origin by default. … `git stash`” command to save you current work without making a real commit, but it is another complication of the workflow. The “local view of the remote repository” is even more elusive. It is the local cache of what we know about the remote repository and its history. This cache may or may not correspond to the actual status of the remote repository, sometimes leading to confusion. It also also not helping that when switching to Git people try to embrace more complicated branching models than they used before. This is not really Git’s fault, but the developers are now hit with the inherent complexity of Git workflow multiplied by the complexity of the branch mode, and the productivity suffers. … ### “One repo is one project” policy Unlike SVN/Perforce/TFS/etc., in Git you cannot clone, tag or branch just a part of the repository. You can only branch or tag the whole thing. This means that if you have multiple projects, you are forced to keep multiple git repositories. This is good for performance, but makes things hard to find. Someone must keep track of all those repositories, and it is left beyond the scope of Git proper. This limitation makes transitioning large SVN projects difficult. Besides, projects sometimes do require common parts. This led to introduction of another new concept: the submodule, with its own set of operations and command line switches. ### Limited/outdated information about the remote, misleading messages Git will read the status of the remote server only when specifically instructed. This leads to at least two issues. Firstly, “ `git log`” shows only your local work, plus the work done by other people before the last pull. There is no easy way to see what is currently going on in the remote repository, unless this functionality is provided by non-git tools, such as Github. … ### You can lose work! In SVN, once something is committed to the server, it is pretty much secure, barring server failures. Not so in Git. Firstly, if you forget to push your stuff to the remote, it is easy to lose it: local folders get overwritten, deleted, etc. However, even once pushed, your commits are not entirely safe. Deleting Git branches may make some commits *unreachable*, i.e. they no longer belong to the history of any branch. Such commits will be quickly deleted, which may lead to loss of work. … But I missed the main ugly point of git for me: The combination of files in your working copy and local Git repository creates some kind of magical “state” defining what kind of operations you are allowed to do. And it is easy to get your working copy to a “state” where you can’t do the things you want, for example change the branch. This can happen by some kind of broken merge, rebase, whatever or just by modifying a file. With SVN if something went wrong you delete/move away the files making troubles and make a svn update. With Git you start googling how to resolve the situation. Additionally it is with SVN absolutely no problem having multiple checkouts of the same project e.g. with several branches while with Git this due the “refresh from remote repository” problem much more annoying. And all these problems just to do “offline” commits (I think 98% of the work is done while having a reliable connection to the repository)?

Source URL

https://ikriv.com/blog/?p=1905

Related Pain Points

Risk of permanent work loss through unreachable commits

8

Uncommitted or unpushed work is easily lost through folder overwrites or deletion. Even pushed commits become vulnerable: deleting branches makes commits unreachable and subjects them to garbage collection and permanent loss, creating data safety concerns.

dataGit

Confusing and inconsistent state management in working copies

6

The combination of working copy files and local Git repository state creates a 'magical state' where certain operations become impossible (e.g., changing branches after a broken merge). Developers must search for solutions rather than having straightforward recovery paths like SVN's simple delete and update.

dxGit

Inability to clone or branch parts of a repository

6

Git's 'one repo is one project' policy prevents partial clones or branches. Teams must maintain multiple Git repositories for multiple projects, forcing manual tracking and introducing submodule complexity. This makes migrations from SVN extremely difficult.

architectureGitsubmodules

Mandatory duplication of branches and tags across local and remote repositories

5

Branches and tags must be created twice—once locally and once remotely—or they remain visible only to the creator. It is difficult to check which branches were pushed, and tags are not pushed to origin by default, creating workflow friction.

dxGit

Excessive workflow complexity requiring explicit push operations

5

Git requires developers to explicitly push commits to origin after local commits, creating a two-step workflow more complex than traditional VCS. Developers frequently forget to push, leading to confusion when colleagues pull and cannot see changes.

dxGit