Hacker Newsnew | past | comments | ask | show | jobs | submitlogin
Learn the workings of Git, not just the commands (2015) (ibm.com)
130 points by philonoist on Jan 18, 2022 | hide | past | favorite | 94 comments


It's been over a decade and I still find this joke amusing:

> @wilshipley git gets easier once you get the basic idea that branches are homeomorphic endofunctors mapping submanifolds of a Hilbert space.

* https://twitter.com/agnoster/status/44636629423497217

(It's a 'spoof' on the Monad joke.)


Mandatory plug for the best git docs on the internet: https://git-man-page-generator.lokaltog.net

For example, ```git-dissect-tipdissects indexed local tips from all noted downstream upstreams, remotes commit graphs, etc.```

Anytime somebody is confused or stuck with Git, it's a great idea to helpfully send them some documentation links from there.


Why does any post discussing _any_ aspect of git always results in these type of comments? "git is complex", "git command line is confusing me", "life would be easier is we all used subversion".

Please let us discuss git in peace.

(Although I admit that this one was funny)


>Why...

Because lots of people don't want to learn git. They want to bungle through it the same way they bungle through most of the software they touch. People who work with software professionally are very adept at bungling. Even through complicated professional software that other users would need training for. But git is resistant. Even rote memorization won't let you hide completely from learning git. There's a steep learning curve before you can half-ass it.

Depending on perspective this is either a damning indictment of git, or just another day at the office.

I've been helping people learn git for over a decade now. Unironically the easiest to teach are interns.


I am using git as a version control system via Tortoise GIT which does a great job of exposing the minimum required functionality of git (maybe a bit more than minimum) and it is only when something goes wrong or I need advanced features that I have to fall back on git command line. So 99.99% of the time I use 10% of git functionality. Even if I did learn all of git (and I doubt there are many people that can make that claim), I would probably forget most of it by the next time I needed to use a particular feature. The main thing that should be explained at the start of any git related tutorial is how git handles the full workflow (from remote to local to work copy and back) because that is one thing that is missing but once you know it the rest becomes easy to understand.


> Because lots of people don't want to learn git.

The thing is that something as trivial as version control should not require that much learning. Pretty much all version control systems other than git had already achieved that (by not providing such a vast "feature surface").

Of course this isn't exactly git's fault. It was developed specifically for Linux kernel developers, not (for instance) for artists on a game development team. The problem is that nowadays, people start to get the impression that git is the only version control system, and want to use it for things it wasn't designed for.


Version control contains problems that are not trivial. Git exposes the right parts of the problems and conflicts for the user, that are in no way trivial for a computer and require human decisions on what should be done with them.


For SOME projects, that rely on a truly distributed model.

Most don't.

Most at GITHUB don't. It's why they use github.


> "git is complex"

Because it is.

> "git command line is confusing me"

Because it does.

Life being easier... maybe, I'm sure it would be for most projects. For some where git is required, likely not. I'd reckon MOST projects don't really need a DVCS; they have the much easier mental model and work quite well with a centralized "source of truth" that people can take from or give code to (coughgithubcough)


We can stop with these comments after another system displaces git as the dominant player.


A mucher better explanation of git interals:

https://git-scm.com/book/en/v2/Git-Internals-Git-Objects

It is surprisingly simple and efficient. I am starting to think this Linus guy knows what he is doing.


He offloaded the complexity to its users! :-)

If the command and option names had just been sensible, it would be a lot easier to learn and use. Half the usability difficulty, maybe more, is just this.


> If the command and option names had just been sensible

Holy shit, yes.

`git branch` in gitspeak really means `git branch list` in human-readable CLI

But `git branch ${NAME}` does not mean `git branch list ${NAME}`, instead it means `git branch create ${NAME}`

There is no `git branch switch ${NAME}` but instead it's `git checkout ${NAME}`

There is no `git branch log` – that would be `git log`, whereas if you want what should be `git log` what you really want is `git log --all`

Don't get me started on whether modified files are added, staged, or indexed...


They are added, staged, indexed, AND cached!


Complexity is unavoidable in the long run, but must be engineered out in the short run.


I still very much recommend the Peepcode Git Internals book.

https://github.com/pluralsight/git-internals-pdf/releases


I like the attitude of "learn the principles of the simple building blocks behind it" as a good next step from a freshman that just memorized "add, commit & pull/push"

But most headache (and heartattack) inducing part of Git when I was a beginner was the "remote vs local repo" and additional complexities this concept introduced. Nothing more stressing for the new guy than making mistakes that screw up for others (mistakeful push, merge, mostly ) or if he think he did.

The article does a poor job (imo) regarding this. It skims on a 2 paragraph "Caveat" section how rebase(and later squeeze) can fuck local vs remote repo, but for most people I know, stress memories around this is what made them learn more about Git beyond than "branch & history keeping software & commands.

That and if you unfortunately end up in a project that uses subtree or submodules


“You need to use git diff --cached to see what is actually in the index: the staged changes.”

Like LOTR, everyone has more than one name.


Git's CLI is it's greatest weakness. Someone should really just scrap that part and rebuild it from scratch on sane ground.


And, unfortunately, the CLI is git’s greatest strength as well. Git was designed for the command line only truly flourishes there, for advanced workflows. The GUI tools that wrap git, and web interfaces like github, only provide access to a subset of what git can do.

It’d be interesting to see what a good redesign might look like. I do think some of the command names and command flags could be superficially updated/renamed/moved and provide a meaningful impact on git’s usability and learning curve. I’m curious though about whether the conceptual part of git is the primary source of difficulty, whether git is fundamentally a little hard to learn, because it’s fundamentally a little bit complex. If that’s the case, a rebuild might not help, there might not exist the kind of “sane ground” to build on that you hope for.


For 20 years I keep hearing these types of complains about Git, Perl, GPG, etc. If you really need those tools than things like syntax, arguments and flags need a little time investment, but after a while they become second nature and you don't even think about them, but about the hard problem that is being made possible to solve by said tools.

These are not toys, one should not expect to just jump into them and start doing work like you would not just jump into a Boeing 747 and just take off, fly and land. It having 100s of buttons is not a weakness.


You mean like: https://gitless.com


Or my own project: https://github.com/martinvonz/jj.

I think https://github.com/Byron/gitoxide also plans to provide a different CLI, but I don't think they've started working on it.


Poe's Law is getting me on your comment. If it wasn't sarcasm, what's an example of a weakness? IMHO, there's a learning curve to using git and especially getting to the point where you can be your team's go-to person for git questions. However, I hold the opinion that of the many technologies out there, git is among those that is worth any investment you can make in learning it. Personally, long term use of git has affected the way I code to bring more intention and organization to what I'm doing.


quick: explain to me the difference between "git reset", "git revert" and "git restore", without looking up the docs.


But are these things a normal user would need to care about?

I bet if you created a great git desktop app with outstanding UI it would still have a few corners 99% of users would never touch or understand.


> But are these things a normal user would need to care about?

... yes? I've used all three of those commands in the past, although I don't remember what they do. and I'm hardly a git expert.


How to undo a change or revert to a previous version? That sounds like a pretty fundamental thing that a user would need to do, yes.


It is usually as easy as "git checkout ID".

If that doesn't work you probably have done something really bad to begin with.


That's probably not what you want. Checking out an ID would put you in a detached HEAD state, and the CLI will give you the page of warning messages that go along with it. I think that this is an excellent reminder that yes, the git CLI is not simple or obvious.


Hmmm....

    - reset: "blindly" load whatever commit you tell it into your working directory. This is the one if you add "--hard" will plow over your working directory in a way that cannot be undone. Actually I think without the "--hard" it won't make any changes to your working directory, it will treat whatever is in said directory as a change from the commit you told it to reset to. Dunno... have to look into it.

    - revert: Creates a new commit that undoes whatever commit you pass in.  Often times people mistakenly use this to "undo" a merge into a production branch that shouldn't have happened. The result is trouble when they want to push those changes back into production again.

    - restore: I have no clue what this does.
All I really know is "--hard" is one of like two commands that you can do in git that you can't back out of. "git clean" is another one (I think).

Yeah... conceptually Git is kinda easy but the command line is pretty nuts.


I'm pretty basic with my Git knowledge. I can merge, rebase, reflog, and the other basic things. However, even I know the difference between reset, revert, restore, and generally use them daily.

Now, I generally do not remember many of the extra arguments that can be passed apart from 'reset --hard/--soft', 'git log --stat/--oneline --decorate', etc.

Personally I've found git complicated when I've worked at a place with bad 'git' discipline. When I've worked at companies with sane branching agreements, etc. I rarely face problems.


Maybe you are newer to git, but this does not feel like a good faith comment, because “restore” is a command that was added specifically because people complained that the overloading of “checkout” is confusing.

Anyway: “reset” changes the ref to which the HEAD branch points, and depending on options can also update the index and working tree to match as well. “Revert” creates a commit that is the reverse of an earlier commit. Restore rolls back uncommitted changes to a file.

This isn’t hard?


What definition of hard are you using? It's an industrial strength tool used almost exclusively by professionals and expert-level amateurs. It's definitely hard, the same way knowing what to do with a welding machine is hard.

On the other hand, even among the professionals it has a reputation for being tricky and frustrating. Which is not the norm for most critical daily-use tools in this or any professional. So I'd also consider it hard in that sense.


Don’t forget rebase if we are doing this.


git reset: unstage a change

git revert: create a commit that reverses a previous commit

git restore: you got me. I can't remember


Reset is more overloaded once you add parameters.


> Git's CLI is it's greatest weakness

Git’s CLI is good as a unix-philosophy low-level tool that user-friendly tools can build on, and is a strength in supporting a wide range of different workflows.

It's suboptimal as a end-user tool for most workflows, but not bad enough for that people consistently build tooling rather than guides for particular workflows.


Yes, magit.


Understanding what git is doing under the hood did more for my ability to use it effectively than it did for most tools.

That said, this document in particular does not seem to be a very good way to get that understanding, it's a very "IBM documentation" way of presenting git. I wish I remembered what I read, because it's was a much easier read.


Perhaps it was Pro Git's chapter 10: Git Internals(1)? I once used it as a guide when writing a basic 'git inspection' tool and definitely found the whole experience useful for getting a better understanding of Git.

1) https://git-scm.com/book/en/v2/Git-Internals-Plumbing-and-Po...


For me it was "Git for Computer Scientists": https://eagain.net/articles/git-for-computer-scientists/


Maybe the git man pages? Iirc the man pages have 2 or 3 'getting started' documents that really made me feel confident. Then I didn't use it for two years and now it's real fuzzy again.


I found the Git section of "The Missing Semester of Your CS Education" to be helpful.


Seconded, here is the link: https://www.youtube.com/watch?v=2sjqTHE0zok.


In my experience it is fine to first learn only some required commands. One will run into cases, where ones understanding or imagination of how git works will not work any longer. In such cases one can still read up on how it works and build a new working understanding. Only important to not always just shrug, delete the repo and clone again. That will not really facilitate learning.

Of course no one is stopping anyone interested in it from reading more about how it works up front.


This usually leads to "my shit's due in an hour, my repo is totally broken and I have no idea why... HEEEEELP".


I'm new to git. For now I use it from VSC, but I should probably give CLI a chance.

I must admit that I'm at the point where I shrug, delete and clone the repo if I'm stuck. Some errors and messages were to cryptic to me.


"In this case, the conflicting result is left in the working directory for the user to fix and commit, or to abort the merge with git merge –abort."

I've used git for many years, and I still zip the repo folder, before doing a large merge, since 'fix the commit' can be a large effort with conflicts. Quickly renaming the repo root folder, then unzipping the old version can be quicker/safer, if you are not a git ninja and don't want to loose any work. There is probably proper command for it, but I sometimes get into a git mess that I cannot get out of. (reading stack overflow, trying get reset, git checkout, git reset --hard and so on)


Quick tip: Git branches are cheap. Like super-cheap. IF you want to create a safe point just before doing a tricky merge, just spin off a new branch pointing at the current commit:

git branch blah_branch_backup

Later, if your merge gets completely messed up, you can do:

git merge --abort

git reset --hard blah_branch_backup

That final command will restore the current branch's HEAD to point to the same commit as blah_branch_backup.

This same pattern is useful for other dangerous commands, like rebases or filter-branch.

When you're done, just delete blah_branch_backup.


You can also use git-reflog to restore the branch back to the state it was before the merge. So instead of creating a temporary branch, you can inspect the reflog, find the entry before the merge commit and do git reset --hard HEAD@{X}.


That's true! I personally prefer having a symbolic name for my backup, but the reflog is also very useful for "oops" moments.


reflog saved me a few times, just remember that commits not referenced by a pointer (like HEAD or branch) can be GCed and disappear at any point. They are likely to be there right after a merge/rebase is finished, but may not be there anymore an hour later.


Afaik git branches are merely pointers to commits, so it makes sense, that one can go back finding the correct commit id.


Thanks, I should have been mote precise in my post. I meant, I zip repo root folder before a complex git operation (certainly not before every single merge).

One example: changing the commit email, somewhere on the middle of many commits. On github, I sometimes need to use the work email instead of personal email (due to https://github.com/apps/google-cla) Changing the email of an existing commit messed up my repo beyond repair. This is just one example from memory, it happens infrequently luckily. Thanks for the git tips :)


That's exactly the sort of operation for which backup branches can help.

When you rewrite history, Git makes new commit objects that have the same topology as the original branch topology. It also updates the branch pointer to point at that new HEAD commit.

History rewriting commands essentially just fork the repo at some point in the past and create an alternate commit history. The original commits still exist, at least for a little while. Git will eventually garbage-collect them.

By creating a backup branch, you're "pinning" those old commits. With the backup branch in place, after you run a command that rewrites history, you will be able to look at the commit graph and see the point where the backup branch and the rewritten branch diverged.

I used to do what you do until I learned more about how Git works internally. And Git's really not super complicated at its core. I think much of Git's complexity comes from the minutiae of the CLI options. (For example, when you want to delete something, do you use `-d` or an explicit `remove`? It depends on the command you're running.)

But hey, if you have a workflow that works, then you do you.


I create backup branches all the time. Though I rarely have to use them, they have saved my butt a couple times!


You don't need to create backup branches ahead of time with git, because the reflog saves every branch before every operation. You can create your backup branch from the reflog _after_ you discover you need it!


I did use the reflog once, when I forgot to make a backup branch. It's not one of the commands I use regularly though.


> git branch blah_branch_backup

Don’t forget to commit your changes if you’re going to `reset --hard` later!


> There is probably a proper command for it

Before you merge, the command is “git merge --abort”. After you merge, the command is “git reflog” to show your history, and then something like “git reset --hard HEAD@{1}” where the number in braces is the reflog entry you want to restore.

Reflog is the ultimate undo tool for work that’s been committed, it’s like having an infinite Ctrl-Z. If you use reflog to restore before your merge, you can even use it again to restore your mess, or to restore a different merge before the one you made a mess of.

The one thing you can’t recover using reflog is an accidentally dropped git stash. This is one reason I try to avoid stashes, and just use lots of one-off branches instead.


I'm the same - although I've had many experiences in the past where I avoided the time-saving tools because they were too complex in the moment and then kicked myself later on when I realized just how much time I had been wasting by avoiding spending ten minutes learning the time saving tools, every time I try to do a git merge "the right way", I end up with conflicts that shouldn't be conflicts and changes that I didn't want to pull in that I have to manually undo until I just give up and "manually" merge.


"Zipping the folder" and keeping a copy of it is literally the sole purpose of a version control system. These kind of comments baffle me, quite honestly. But that is my fault, not yours.

Could you tell me what you think git is for and why you use it?


Congrats never getting into a time consuming git mess, but I do sometimes. This is a very rare event. Recently I tried changing the committers email (each commit has a name and email attached) but that commit was already pushed into the repo, and I could not recover from the resulting mess. Even had to delete my github fork, and fork again. Happens about twice a year, while I used git commits many times every day.


This sort of use case makes sense to make a copy of the .git folder. When you are trying to rewrite the history of a whole Git repo, throwing away the repo and starting for a backup is often easier than trying to unwind changes.

Though in this specific case of rewriting emails, there is a way in git to do it without rewriting history:

https://git-scm.com/docs/gitmailmap


You misunderstand. Do you think I was born understanding how git works? I've messed up at least as much as you, but I spent the time learning how it works rather than going nuclear and deleting the repository. I can't relate to how you think about git because it's been too long for me, that's why I asked if you could explain it from your point of view.


Ooof. What a useful contribution to the discussion.


Are you really shocked that someone would make a backup before doing something they are unsure of?

Personally, I git clone a fresh copy to do any advanced stuff in, and sometimes an extra just as a backup. Though that's not really much different than copying the folder. Especially if he has uncommitted files like IDE settings and whatnot he doesn't want to fix if things go really bad.


> Are you really shocked that someone would make a backup before doing something they are unsure of?

No, but I'm shocked git is so misunderstood that this would be considered a time to do this.

Keeping a backup of previous versions is git's raison d'être. If you can't trust git to do this, how can you trust "cp" to make a copy of a file? I would love to get a genuine answer to my question: what do you think git is for and why do you use it? This would help me enormously to understand where you are coming from.


Git is a popular distributed versioning tool, but some commands have obscure syntax that is easy to get wrong, leading you into a mess that becomes a time drain. Creating a zip file of a git root folder takes seconds, and can get you out of the mess in seconds, rather than spending minutes or hours to undo some mess. If you can foresee git getting into a mess (and I can, after > 10 years of git experience), you can just take that backup to save time 'just in case' your git repo gets into that mess again.

Changing the git commit history (for example because you made a commit under the wrong name/email address) in particular can cause huge headaches.

Doing a git merge with tons of changes (think of clang-format white space changes in combination with various other commits) is another one.

This is not about the specific cases where your git repo can become a mess, but more about having a simple safety mechanism to always get you out of the mess.


Backups and version history are not the same thing. Especially when you're messing with the version history. I make copies when I'm using git-filter-repo, or BFG. But even rebase is a destructive action that would be nice to have a safety net for.

In the real world people have a ton of untracked files for their development environment, and uncommitted changes, but need an update from a coworkers branch that has a conflict with development, and a different conflict with your local changes. This can leave you in a weird state pretty quickly, and merge conflicts are a pain, especially if the conflicts are in a part of the code you're not very familiar with. Personally, I go full cowboy and work my way through it, but I am not surprised in the least when I hear that people make a backup so they can quickly restore.

One benefit of copying a directory instead of using git is that it will copy all of your untracked files, and uncommitted changes as is. Another benefit is that it works the same no matter what tooling you're using. I believe that some legacy code at my company is still on SVN and source safe. I also use open source projects that are developed with mercurial, bazaar, and fossil. If I were going to work on any of them, I would definitely be making backups the standard way instead of trusting my ability to use the tool properly.


> No, but I'm shocked git is so misunderstood that this would be considered a time to do this.

You shouldn't be. As you say, you shouldn't need to do this, but the fact that so many people do feel the need to do this speaks to poor UI design on git's part. There are, I think, two main reasons why people feel the need to do this.

The first is that git makes it really easy to rewrite history, without really offering much in the way of safety rails. You have but to be burned by this once to lose all trust in git whatsoever. And this is something where there are safer ways to rewrite history: Mercurial's concept of phases or changeset evolution is easily far better than git in this regard. Even exporting the excised revisions as a revset ("strip-backup") is far easier for me to undo than having to go into git reflog (especially because I don't need to race any `git gc` command--note that git is the only VCS that feels the need to have a garbage collector!).

The second issue is that git has a lot of different places where state can be hiding, and it quickly becomes unclear which of the various places a command is affecting. Is this going to update my working directory, the most recent commit, the staging area, or multiple of those copies? If I'm in the middle of an interactive rebase, do I need to `git commit` or `git commit --amend` or some other command to properly update "the" commit? Maybe if you're fluent in git, it's all obvious, but if you're not fluent, it's way too easy to accidentally do the wrong thing. And looking up git documentation doesn't help--it's the only tool I regularly use where reading the documentation actively leaves me more confused than before I consulted it.


> The first is that git makes it really easy to rewrite history, without really offering much in the way of safety rails

It does, I just think they are not obvious enough because people haven't read an article like the one posted here.

Git is an append-only data store. You can't lose anything as long as you have committed it. Rebasing does rewrite history, but it doesn't delete the old history. It's still there. The reflog links to it. The old remote tracking branch links to it. You could even leave a tag there to link to it. There are many ways to get back.


> If you can't trust git to do this, how can you trust "cp" to make a copy of a file? I would love to get a genuine answer to my question: what do you think git is for and why do you use it? This would help me enormously to understand where you are coming from.

All of us - at some point - were new to git and coming from other VCS systems meant there was a relatively steep learning curve.

I also understand git fear - some of the stuff is a little arcane, and organizations are often very dogmatic and loud about their usage and approaches to git. It leads to a lot of gatekeeping. Do we rebase here? Do we never rebase? Linear history? Rebase feature branches or merge directly into main? It makes the fear of the tool that much stronger.

`cp`, on the other hand, is pretty straightforward. There are no local approaches to using it, there's no real `cp` expert in-house at most places. It does what it says on the box without a lot of frills or options.

git is a complex tool. It becomes easier the longer you use it, like most things, but it can be very intimidating to new or intermediate users.


> All of us - at some point - were new to git and coming from other VCS systems meant there was a relatively steep learning curve.

He's not new to it. He says he's been using it for over 10 years!


Combining a small repertoire of git commands and this type of brute-force backup allows people to use git without having to learning all the details of its inner workings (or at least not having to keep that knowledge in everyday short-term memory.)

If a small repertoire of git commands covers 95% of what a person needs git for, and recovering from backup covers the remaining 5%, why spend time and effort "git-ifying" that last 5%?


It's entirely possible to trust something to work one way (e.g. keep a trivially restorable backup of previous state) when you do one thing with it and not trust it to do the same thing when you do another thing with it (especially if it's something you do infrequently or have never done before). The advantage of cp compared to git is that it only does one thing (more or less), so you don't have the potential for "doing things you're unsure of" in the same way as git.


> Could you tell me what you think git is for and why you use it?

Maybe it's not your intent, but you're coming off as a bit of a git yourself. He lacks your confidence.


> He lacks your confidence.

But why? I'm trying to learn here. I'm know I'm autistic and don't understand anyone. It's clear that there's a huge difference in how I perceive git versus how a lot of people apparently perceive it. I'm trying to understand how other people perceive it but nobody will tell me!


There is a great tutorial which teaches git internals by implementing git in python: https://www.leshenko.net/p/ugit/


As a user, I see absolutely no reason to know the internal workings of Git. It supposedly offers a service, which is tracking and recording changes to files. In a way, it's a very able SaveAs/Open command and also offering some way of altering the recorded history.

How it's done internally, as much as it's remarkable, is just an implementation detail. The fact that users are repeatedly being referred to docs/books, points to conceptual inconsistencies or mismatches in the intended application contexts.

As a user I operate with directories and files. Now version control also introduces a time-component, which is versions (and version of a version aka branch) and some kind of history/timeline/journal/log.

Why would a branch have a "head" and "base", isn't parent/child concept expressive already? Why "ref", if we've got "version" already? Why "stage", "index", "cache"? Why "cherry-pick" if we've got "patch"? Etc.


One reason why you would want to know how Git internally works is to make a better use of it. The interface it exposes is relatively low level and as such suffers when uses don't understand how the software internally operates. If anything, used being repeatedly pointed to docs shows the lack of understanding of Git's inner workings.


As much as I love and depend on git, the visible user interface seems a bit ugly. You can get used to it over time, but it has a certain non-unix flavor that I dislike...

There should be a purely unix way to use git, as in "everything is a file". Sure, you can go to the .git folder and there are files in there. But the structure of these files does not directly represent the structure of the repository. What I want is to "mount" a git repository, so that I can explore its contents using cd, ls and cat. Also, by editing these files I implicitly make commits and create branches to the underlying structure. Would that even be possible?

EDIT: A disturbing feature that I don't see a way out is that in git there are "standard" and "history-rewriting" operations, and there is a clear distinction between the two. To what would that correspond in terms of pure file operations? Something about changing the default permissions?


> A disturbing feature that I don't see a way out is that in git there are "standard" and "history-rewriting" operations, and there is a clear distinction between the two. To what would that correspond in terms of pure file operations? Something about changing the default permissions?

> "history-rewriting" operations

Git is a Merkle hash tree. You can never rewrite history. Instead, what you think of as "history-rewriting" operations is just "non-fast-forward" changes to branches. Branches are really just named pointers -- {branch_name, commit_hash}. A change to branch from {$name, $commit0} to {$name, $commit1} is fast-forward IFF $commit0 appears in the linear history of $commit1. A non-fast-forward change to a branch is what you call a "history-rewriting" operation.

There's nothing wrong with "history-rewriting" -- I do it all the time. It's only ever bad when you do a non-fast-forward push to a branch that others track, and even then it's not the end of the world because usually those others can recover easily enough with `git rebase --onto`. Rewriting the history of a public branch is a problem, yes, because you want the history to be stable and reliable so you can use it to figure out problems, understand the history of the project, etc, and because making others have to `git rebase --onto` is impolite.

It's essential to understand that the only destructive operations in git are a) non-fast-forward branch changes, b) tag changes, c) gc/prune operations when you're like me and you're used to working in detached-HEAD mode.

If you're stuck on "Git has history rewriting, and that's bad!", then you've misunderstood everything about modern version control systems. You can -and I have- do the same sorts of destructive operations in version control systems going back to the early 90s (e.g., Teamware, CVS), to say nothing of newer ones like Mercurial, Fossil, and, of course, Git.

Inb4 "But Git encourages history rewriting" -- that is neither true nor a good argument.


> What I want is to "mount" a git repository, [...] Would that even be possible?

Yeah, sure, why not? You could do it with fuse http://libfuse.github.io/doxygen/ There's even a git fuse filesystem already out there. I dunno if it works the way you want though.


If I might offer a suggestion, instead of using various git commands, you want to be able to just cp a folder to a mounted git folder, and echo the commit message to a .commitmsg in that folder, or something like that, right?


Yes, but not only that, I want a folder for each commit, with all the files inside it, including a .commitmsg file with each log message. Thus "git log" could be implemented as

    cat `find . | grep commitmsg`
More interestingly, it would be able to grep around all previous versions of the files.


Feeling required to post about the Building Git[1] book, really love it, for anyone interested in a walkthrough of rebuilding many of the most of important git features, from scratch, in ruby.

[1]: https://shop.jcoglan.com/building-git/


Excellent! Two updates since it was written: use main rather than master for the default branch; use git switch to change or create branches.


Pffft, as if anyone actually could just use Git commands without learning the internals.


The important thing to understand is that git is a blockchain


It goes a lot further than just being a blockchain. Git is a DAG through and through. But this might actually be the best way to make some people understand it. I was gobsmacked one day when a colleague came into work and they were really excited as they'd realised git is actually a blockchain. I was stunned as it seemed so obvious, but if they only just realised then how had we been working successfully with git for so long?


A blockchain is one linear branch. Git is just a tree of them, but they're all blockchains.

The only other extremely important thing to understand about Git is that it has a way to name commits symbolically (branches and tags), and that those names can be changed, and that leads to understanding what a fast-forward and non-fast-forward change to a branch really is.


So each commit is an NFT. Now, where’s my million dollars?




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: