Skip to content

Commit

Permalink
deal: update README.md
Browse files Browse the repository at this point in the history
  • Loading branch information
lijie78 committed Feb 23, 2021
1 parent 319b2f8 commit 51dcd2b
Showing 1 changed file with 28 additions and 74 deletions.
102 changes: 28 additions & 74 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,81 +1,20 @@
# ZIT development log
# [ZIT](https://github.com/ReZeroS/zit) development log

## Summary

原作者地址: [https://www.leshenko.net/p/ugit](https://www.leshenko.net/p/ugit)

`git` 挺感兴趣,就照着实现了一个java版本的,感谢原作者。
Thanks for the great tutorial: [https://www.leshenko.net/p/ugit](https://www.leshenko.net/p/ugit)

- 2021.02.21,原作者在文中使用了一些辅助工具, `zit` 项目尽力去实现了这些部分,比如 `diff``merge` 的算法,但是能力时间有限,这里只写了较为简单的版本, 比如没有线性优化的 `myers diff` 等, 所以欢迎优化

- 此外作者的原项目用了一些 `Pythonic` 语法糖,这里也尽可能在 `java zit` 中简易的方式实现,方便其他语言的开发者阅读

## TODO

1. git hash-object todo. When real Git stores objects it does a few extra things, such as writing the size of the object to the file as well, compressing them and dividing the objects into 256 directories. This is done to avoid having directories with huge number of files, which can hurt performance.
Thanks again Nikita!

## Resource

## Notes
I found some good reference material, and I put them under the `./doc` directory.

1. 这个暂时记录下,没查明白:打包用 shade, 要不然要和 classpath相关联导致idea运行没啥问题,打包后却各种问题
Besides, the follow links maybe help you too.

2. 命令行解析用了 `picocli` 这个库,可参考 `git init`, `git hash-object` 了解基本使用,很容易上手且巨好用,简答说命令行的参数就两种,`options``positional parameters`,参考下图
- [robertelder](http://simplygenius.net/Article/DiffTutorial1) this post is short but enough to help you have an higher level to understand diff
- [jcoglan](https://blog.jcoglan.com/2017/02/12/the-myers-diff-algorithm-part-1/) this posts make a detail description about the diff.
- [visualize](https://blog.robertelder.org/diff-algorithm/) if you wanna have a debugger or visualization about diff algorithm, this will be a good choice.

![options and param](./doc/OptionsAndParameters2.png)

3. 工具库用了 `guava`, 里面的方法都是 `@Beta`, 所以后续看看是不是要提取下或者用 `zerobox` 作为依赖

4. 关于 `write-tree` 几个注意点

- 对象分两种,一个 是 `tree` 代表目录且仅返回一级目录的情况, 一个是 `blob` 即文件
- 在递归过程中不要忘记了路径的变换要带上前置路径来确保总是使用同一个位置的相对路径
- `File` 类为空文件夹 `listPath` 会返回长度为 0 的数组,只有当不是文件夹时该函数才返回 `null`
- `listFiles` 获取的 `File` 列表中的 `file` 调用 `getPath` 返回的路径是拼接前置路径的,但是会因为环境的不同,路径的分隔符就会不同,这点需要考虑到 `ignore` 函数上

5. `os.walk` 的返回值是一个生成器(generator),也就是说我们需要不断的遍历它,来获得所有的内容。而每次遍历的对象都是返回的是一个三元组(root,dirs,files)

- `root` 所指的是当前正在遍历的这个文件夹的本身的地址
- `dirs` 是一个 list ,内容是该文件夹中所有的目录的名字(不包括子目录)
- `files` 同样是 list , 内容是该文件夹中所有的文件(不包括子目录)
- Java nio 包的 `Files` class 也同样提供了类似的功能, `walk` 获取的目录是以传入 PATH 开头的相对目录
- 配合 walk 可用的 `relative, resolve, System.lineSeparator`

6. diff 算法没搞明白(-_- 菜的浑身发抖),暂时收集到这些资料,~~找了网上的一个实现~~ (2020.02.19)自己已经试着写了一版diff ( ・᷅ὢ・᷄ ),后续有时间优化下,详情见 DiffUtil
- `doc` 文件夹下的工具和 paper
- blog
- https://blog.jcoglan.com/2017/02/12/the-myers-diff-algorithm-part-1/
- https://blog.robertelder.org/diff-algorithm/
- http://simplygenius.net/Article/DiffTutorial1
- https://chenshinan.github.io/2019/05/02/git%E7%94%9F%E6%88%90diff%E5%8E%9F%E7%90%86%EF%BC%9AMyers%E5%B7%AE%E5%88%86%E7%AE%97%E6%B3%95/
- 概念普及
- d: 代表步数即最小操作数,我们的第一个大目的就是找出这个最小的数
- 操作:d 每加 1 意味进行了一次 x + 1 + diagonal 或者 y + 1 + diagonal. 其中 diagonal 为遇到斜线的数量
- x, y: 分别指 A B 两个串的行数,x 增加时意味着从 A 串删除, y 增加时意味着从 B 串增加, x,y 同时增加意味着遇到斜线了
- k: x - y 的值
- d 和 xyk 的关系:
- d 代表步数,可以到达点 (i,j), 如果期间经过了对角线, i, j 必定同时加 1
- 由上可得 d 可到达的步数为 (i + diagonal, j + diagonal), 其中diagonal 为经过对角线的次数
- 那么k = x - y = i - j 的奇偶性就依赖于 d
- 当 d 为奇数, i + j 就是奇数,自然 i-j 就是奇数 => d 奇 k 奇, d 偶 k 偶
- k 这里有个重点意识:任何抵达 k 线的点 必经过了至少 |k| 个 增或者删操作
- 最终为了走到格子右下角,那么其实最终的 x, y,k 都已经确定了,只不过要确定的是 d 而已
- d 之所以可以作为第一层循环是因为 d = f(d - 1), 即 d - 1 是 d 的子问题
- d 确定为最外层循环后,k 的范围可以根据 d 来确认,至此,最内层要做的就是找到能抵达的最远的距离,最远距离超过右下角时目标达成,此时的 d 就是最小 d
- 上述推论下问题只剩一个了,如何找到最远的距离?(思考这个问题时先假设没有斜线这个概念,只有纯粹得下或者右,这样可能有助于理解)
- k是以2来迭代的, 每次 `v[k] = v[k-1]` 或者 v[k + 1], 这里由于每次d的奇偶性限定了 k 的奇偶性,其实这里的 `v[k-1] v[k+1]` 取得上轮外层 d 循环得值
- 换句话说 当前轮得 `V[k]` 是指 `V[k+-1]` 走了一步后得结果,而`v[k-1]``v[k]` 一定是 v 往右走了至少一步(超过一步得都是斜线), 所以 `x = v[k-1] + 1`, 而 `v[k+1]` 则是往下走了一步,这时 `x` 不变
- `k == -d`, 此时只能从 `k+1` 往下走( `k -1` 此时还没有值,并且越界,`k+1` 往右走就到 `k+2` 了,所以走了一步后 x = v[k+1] ) 同理, `k = d` 自然 `k - 1` 往右走, 此时 `x+1`
- 其他情况自然取 `v[k -1]` `v[k + 1]` 比较大得那个值
```python
if k == -D or k != D and V[k - 1] < V[k + 1]:
x = V[k + 1]
else:
x = V[k - 1] + 1
```
- 注意斜线必定不可能为起点,因为斜线不消耗步数(上一步走到斜线必定会走(白嫖)完(因为探讨的是 k 的最远达而最终点的最近可达点)),所以只能是斜线为终点,不可能作为起点
- 上面这个推论用在回溯上就是如果发现上个节点比当前节点的 x, y 都小,那么可以直接 diagonal 到x 或 y 与前面一点相同时,这时应该最多只需一步便可到达目标节点

7. Java 切换目录比想象得要费劲,可以试着了解些这个包 `com.github.jnr/jnr-posix`
If you feel interested about this project, you can post your idea on the discussion or just contact me with email.

## Usage

Expand All @@ -92,7 +31,7 @@
- Get the path of the file to store.
- Read the file.
- Hash the *content* of the file using SHA-1.
- Store the file under ".ugit/objects/{the SHA-1 hash}".
- Store the file under `.ugit/objects/{the SHA-1 hash}`.

3. `zit cat-file hash [object|tree|commit|...type]` print the file content

Expand All @@ -119,7 +58,7 @@

9. `tag` will alias commit id, and at this time, you will get first inner core concept.

- [git-ref](https://git-scm.com/book/en/v2/Git-Internals-Git-References)
- [git-ref](https://git-scm.com/book/en/v2/Git-Internals-Git-References) the official post will help you learn some basic knowledge about the git.

10. todo: `zit lg` graph feature with Graphviz

Expand Down Expand Up @@ -155,4 +94,19 @@
- pay attention: diff3 will leave merge_head in the zit root directory and that means you need to commit manually.
- `zit merge-base` is used to help the merge command find the first common parent commit of the commits which will be merged. But you also can use this command to do debug task.

19. `zit fetch`,
19. `zit fetch`, `zit push` these two combined commands are used to download or upload objects and update the ref.



## Summary

### UPDATED 2021.02.21

- implemented the diff(myers diff but without linear space optimized) and merge algorithms(simple diff3) instead of using unix tools.

- `Ugit` use some cool `Pythonic` code while zit trying to make code easy understood for the other language developer.

### TODO

1. git hash-object todo. When real Git stores objects it does a few extra things, such as writing the size of the object to the file as well, compressing them and dividing the objects into 256 directories. This is done to avoid having directories with huge number of files, which can hurt performance.

0 comments on commit 51dcd2b

Please sign in to comment.