Live data from Hacker News

Git Exercises

gitexercises.fracz.com

21–30 of 45 posts

Re: Git Exercises

#21

Earlier quoted context omitted.

On 1.: As others already noted, Git has a GC-mechanism, which means that objects can still linger around in any copy of your repo for a while. And if you need to version binary files, you'd better use git-lfs or git-annex. Obviously, if you don't need them, just nuking them outright with BFG or `git filter-branch` is fine, too. If you'd like to try git-lfs: It also includes tooling to retroactively migrate your Repos…

RE #2: (First, thanks for everything!) Our regular routine at the time: Imagine production and dev are even. We add 5 regular commits to dev. We PR merge dev -> production. We do not do squash and merge. We do not delete dev. Dev and master are now even but master has the merge commit as well. Flash forward several years. Looking at history, we now see each of those 5 commits for a run of about a year appear multiple…

No problem. Glad to be of any help :)

I'm sadly still not all that sure I understand you correctly (and I'm afraid I can't tell you exactly what caused your issue), but:

If it is the commits that "do the work" that are duplicated (not the merges), I'd guess there already was someone (or some script/tool) that already rewrote history a couple of times and not everybody was aware of that.

If your team didn't look much at the history structure and try to actively shape it in a certain way, this could just have happened because someone did an innocent `git pull` after the history of the branch had been altered on the server.

`git pull` by default equates to `git fetch` and `git merge`, so if your history was altered, the branch would contain copies of the original commits (with totally new IDs), and git would "knit" the two copies together in a new merge. That means that this probably has happened around five times (since you see five copies of the oldest commits).

In this case, the hashes of the duplicated commits should be different. If that's not the case, I'd guess you have a client that visualizes the history in a weird way and the problem is something else.

Cleaning this up might then be more cumbersome, since the points you'd need to "adjust" weren't committed "back to back". If you're willing to do the work by hand, you could just string together intact pieces of the history into a clean one by using `git rebase` with `-r` and `--onto` (or `git cherry-pick`, but I've never used that one for complex topologies, so I don't know how helpful it is there)...

Re: Git Exercises

#22

Earlier quoted context omitted.

RE #2: (First, thanks for everything!) Our regular routine at the time: Imagine production and dev are even. We add 5 regular commits to dev. We PR merge dev -> production. We do not do squash and merge. We do not delete dev. Dev and master are now even but master has the merge commit as well. Flash forward several years. Looking at history, we now see each of those 5 commits for a run of about a year appear multiple…

No problem. Glad to be of any help :) I'm sadly still not all that sure I understand you correctly (and I'm afraid I can't tell you exactly what caused your issue), but: If it is the commits that "do the work" that are duplicated (not the merges), I'd guess there already was someone (or some script/tool) that already rewrote history a couple of times and not everybody was aware of that. If your team didn't look much…

I just did some experiments, and I think this should help identify such merge commits from the commit IDs of two copies:

Run this in bash (if you're using Windows, use "Git Bash"). Make sure you replace the `` tokens with the appropriate commit IDs. The hash it prints should be the merge commit tying the two copies together.

  commit_1=
  commit_2=
  
  awk '
          ARGIND == 1 { h[$1]++ }
          ARGIND == 2 && h[$1] { last = $1 }
          END { print last }
      ' \
      

Re: Git Exercises

#23
post #14

Earlier quoted context omitted.

The configure.sh script you run at the start creates a few aliases (start, verify, exercises). See https://raw.githubusercontent.com/fracz/git-exercises/master...

Thank you for posting this, when I cloned the repo initially from the site, configure.sh was not included.

Yup, the initial `git clone` is checking out detached head 71c5f2d08f23d30c6fc11ac71d65f683b326c844.

It looks like the remote bare repo has a botched HEAD.

Workaround:

    cd exercises
    git checkout master
    ./configure.sh
    git start

Re: Git Exercises

#24

Responding in hopes some Git non-novices are here and can give some quick advice. I have a fairly large Git repo with 5 years of commits from numerous team members including a bunch of non-technical people who had never used Git before. There were two major issues: 1. We started off storing binary files -- mostly images, but also a ton of raw data files that got versioned every day or two -- in this repro and it spir…

Regarding 2, that branching strategy sounds completely reasonable and simple. You wouldn't except to delete the "dev" branch in that case, nor squash any commits, because "dev" is a shared branch that many people use. It sounds like a classic "test" or "pre-production" branch.

You would expect people to commit cleaned up commits ready to be merged to production into that branch. Any exploratory work would be done outside "dev" (either in developer local repositories or personal branches). It is also important that no commits are ever made to the production branch directly, otherwise your branches would become out of sync.

If you'd like the branches to stay identical over time you can stick to fast-forward merges. The downside is that you lose information about when merges to production were made, which may or may not be a problem for you.

The problems with repeated commits are not caused by your merge strategy. The are caused by people doing strange things with git. It might be hard to say exactly what after the fact, and without seeing the commit history we can only speculate. Perhaps many merges were made with unrelated branches, and what you are seeing is merge commits? Independently of how you proceed with this, you need to educate the users, otherwise they will keep polluting the commit history.

I didn't understand the part about removing the repository and take it to be a joke that went above my head. But obviously this can't be done without altering history. It is, after all, the history that is messed up. Fixing this means identifying which commits can be squeezed or removed from history. You have to look at these commits to find out how. Then you just rebase all commits from the beginning to a new history, and then everyone involved needs to keep working on top of that. Just remember to give the old history a name with a branch or a tag before you get to work, so you have something to reset to, should you mess up.

Re: Git Exercises

#25

Earlier quoted context omitted.

You should use git-lfs for these files. Probably some wizardry with `filter-branch` and adding these files to lfs could debloat your repo once you do a fresh clone from that.

Yeah, we used git-lfs for a while but ultimately decided we didn't need to version the static files and just plopped them on S3 and added a step to the deploy to pull them in. Basically, we initially thought we needed point-in-time versions of a bunch of data files, and later decided we didn't care about point-in-time.

Since I just saw this comment: Note that git-lfs stores your binaries in its own directory inside .git (I currently have no git-lfs-enabled repo at hand, but I think it was `.git/lfs/objects`).

That means that there might still be a lot of binaries inside your .git directory because LFS put them there. Those object files are not managed by Git itself, so forcing GCs through Git won't help in this regard, either.

You might also want to look into `git lfs prune`: https://github.com/git-lfs/git-lfs/blob/master/docs/man/git-...

Re: Git Exercises

#27
Thanks for the resource!

I've noticed that if I run a clone `git clone https://gitexercises.fracz.com/git/exercises.git` it gets cloned in "DETACHED HEAD" mode and I need to checkout master, i.e. `git clone https://gitexercises.fracz.com/git/exercises.git -b master`.

Any idea why that is? (It ultimately wasn't a problem once I switched to master, but without doing so there would be no configure.sh script either and I'm asking in case someone else runs into the same issue).

Re: Git Exercises

#28
post #24

Responding in hopes some Git non-novices are here and can give some quick advice. I have a fairly large Git repo with 5 years of commits from numerous team members including a bunch of non-technical people who had never used Git before. There were two major issues: 1. We started off storing binary files -- mostly images, but also a ton of raw data files that got versioned every day or two -- in this repro and it spir…

Regarding 2, that branching strategy sounds completely reasonable and simple. You wouldn't except to delete the "dev" branch in that case, nor squash any commits, because "dev" is a shared branch that many people use. It sounds like a classic "test" or "pre-production" branch. You would expect people to commit cleaned up commits ready to be merged to production into that branch. Any exploratory work would be done out…

> I didn't understand the part about removing the repository

He was just saying that it could all be "solved" by simply nuking the current repository and starting afresh from the current version of the code. They'd lose all history but they'd also have a clean slate and not have to deal with the errors of the past.

Re: Git Exercises

#29

Earlier quoted context omitted.

Thank you for posting this, when I cloned the repo initially from the site, configure.sh was not included.

Yup, the initial `git clone` is checking out detached head 71c5f2d08f23d30c6fc11ac71d65f683b326c844. It looks like the remote bare repo has a botched HEAD. Workaround: cd exercises git checkout master ./configure.sh git start

> It looks like the remote bare repo has a botched HEAD.

So the guy teaching us git has a messed-up git repo...?

(╯°□°)╯︵ ┻━┻

Re: Git Exercises

#30
post #27

Thanks for the resource! I've noticed that if I run a clone `git clone https://gitexercises.fracz.com/git/exercises.git ` it gets cloned in "DETACHED HEAD" mode and I need to checkout master, i.e. `git clone https://gitexercises.fracz.com/git/exercises.git -b master`. Any idea why that is? (It ultimately wasn't a problem once I switched to master, but without doing so there would be no configure.sh script either and…

It looks like `.git/refs/remotes/origin/HEAD` doesn't exist, which might explain why a fresh clone results in a detached HEAD (i.e. Git should default to being on the branch referenced by this entry).

As for how you can end up in such a state on the remote, I'd actually be interested to know too.

Post reply on HN