5 ms·
Git is not a purely functional data structure [1] [1] man git-rebase
by fpoling 9y ago
Git is not a purely functional data structure [1]
[1] man git-rebase
- 19870213 9y agoBut git-rebase does not alter existing commits in the commit tree, it simply creates a new branch (meaning new commits) on the tree.
- Simon_says 9y agoAlright wiseguy, git gc.
- davidcuddeback 9y agoI don't understand what point you're trying to make. Unreachable data can be garbage-collected in Haskell, ML, Clojure, Erlang, and many other functional (and non-functional) programming languages. What about GC is supposed to refute that a data structure is functional?
- Simon_says 9y ago19870213's point was that a git rebase is functional because it doesn't change existing commits, rather it only makes new ones and moves branch pointers. This is correct. You can also say that git gc is functional because it's only garbage collecting. But you can't have it both ways. The cumulative effect of rebase followed by gc is to delete commits that have a branch pointing to them.
- dustingetz 9y agohey you're getting downvoted bc you misunderstand so insistently and cockily, maybe try asking a question
- davidcuddeback 9y ago> The cumulative effect of rebase followed by gc is to delete commits that have a branch pointing to them. That would be a strictly broken GC if it removes commits that are reachable from branch pointers. Please file a bug report with the git project if you've observed this happening, because it would be inconsistent with the git-gc(1) manpage, which says it only removes unreachable objects.
- rootlocus 9y ago> The cumulative effect of rebase followed by gc is to delete commits that have a branch pointing to them. This is both false and irrelevant. It's false because after the rebase, the branch you just rebased won't point to the old commits. Unless you had other branches there, they would be orphaned. Also, according to the "Notes" section of the git-gc documentation [0]: > git gc tries very hard not to delete objects that are referenced anywhere in your repository. In particular, it will keep not only objects referenced by your current set of branches and tags, but also objects referenced by the index, remote-tracking branches, refs saved by git filter-branch in refs/original/, or reflogs (which may reference commits in branches that were later amended or rewound). Since the commit you were on before making the rebase is in the reflog, it will actually not be GCed (yet) even though there are no branches pointing to them. It's irrelevant because, even if it was true, as long as there are no more objects referencing that commit, it's perfectly eligible for gc. I don't understand your argument that "you can't have it both ways". [0] https://git-scm.com/docs/git-gc https://git-scm.com/docs/git-gc
- dustingetz 9y agogc is actually essential to implementing pure functional programming efficiently on top of imperative hardware (see: structure sharing, an essential optimization that lets functional data structures reuse bits of each other internally for low-cost copy-and-modify, at the cost of making a data structure no longer responsible for freeing its own memory since it overlaps)
- fiatjaf 9y agoI don't see that anywhere. A rebase is just a fork.
- klodolph 9y agoIf Git were purely functional, you would expect rebase not to modify the existing data in any way, and indeed that is exactly what happens. You can create, delete, or modify only the top-level pointers: branch names, reflog, etc. Instead, rebase creates a completely new set of commits, and points the current branch at a new one. This is exactly how functional data structures work in e.g. Haskell, where "inserting" an element into a dictionary means that you get a new copy of the dictionary, and all existing references to the original are unmodified.
- fpoling 9y agoGit rebase alters the structures that are relevant for me, like heads of named branches. In Haskell let bindings are immutable. To reference to the results one has to put them into new bindings. I.e. if Git was purely functional, the rebase would create new names for branches.
- tathougies 9y agoYou can easily shadow a name in a let binding in Haskell For example, let x = 5 in let x = 6 in putStrLn (show x) would print 6. Unless you turn on compiler warnings, there is never a need to choose new names for variables if the old version is no longer needed.
- catnaroek 9y agoShadowing isn't the same thing as redefining. Try evaluating the following expression: let x = 4 ; f y = x + y in let x = 6 in f 10
- masklinn 9y ago> In Haskell let bindings are immutable. Haskell has mutable refs. That's what Git branches are.
- catnaroek 9y agoBut the contents of a mutable ref aren't let-bound.