主頁 > 區塊鏈 > 如何在git中列出所有包含未合并提交的“活動”分支

如何在git中列出所有包含未合并提交的“活動”分支

2022-01-12 19:15:10 區塊鏈

我正在努力理解幾個非常大的存盤庫的歷史,這些存盤庫有數百個(舊)分支從未被洗掉(即使這些分支中的大多數作業已經“完成”)。

我正在嘗試找到一種方法來生成一個分支串列

  • 包含創建分支后的提交(“非空”)
  • 尚未合并到另一個分支

如果我的假設是正確的,這應該回傳包含未合并/活動代碼的分支串列 - 其他所有內容都可以安全洗掉。

一個不錯的噱頭是通過可視化這一點git log --graph- 僅顯示“當前作業樹”,僅回傳所有“當前活動分支”中存在的第一個提交。

非常感謝任何建議/幫助!

uj5u.com熱心網友回復:

TL;DR:git branch --no-merged HEAD可能是您想要的答案。您可能想要添加-r-a,或使用除 之外的其他內容HEAD您可能希望多次運行此(調整后的)命令,為每個分支名稱運行一次(盡管在這種情況下,有一些方法可以更有效地執行此操作,但代價可能這樣)。

重要的是要意識到 Git 實際上并沒有合并分支或者更準確地說,我們必須先定義分支的含義(請參閱“分支”到底是什么意思?);這取決于我們使用的定義,Git不會分支機構,或不合并分支機構,或不合并子公司,但隨后他們有時會取消合并后; 或者還有其他可能性,具體取決于所說的“分支”。?? Git所做的合并——可能對你的問題有用的方式——就是提交分支名稱可幫助您和 Git查找提交,否則這些提交會單獨存在于提交圖中,這就是你將如何使用上面的答案。

Git存盤庫實際上主要是提交的集合Git 不是關于檔案——盡管提交確實包含檔案——也不是關于分支,或者至少是分支名稱(與“分支”不同,它是明確定義的),盡管分支名稱可以幫助我們找到提交。這實際上只是關于提交,因此您需要能夠可視化提交:

一個不錯的噱頭是通過 git log --graph

你可以這樣做,但是:

僅顯示“當前作業樹”,僅回傳到所有“當前活動分支”中存在的第一個提交。

作業樹實際上不是Git的,并給予多么糟糕分支在首位的定義,再加上事實字活躍是完全-defined,我們可能永遠不會知道什么是“當前活躍的分支”,甚至手段。所以我們不可能那樣做。

什么在Git中是提交。提交:

  • 編號:每個都有一個唯一的編號,或哈希 ID,以十六進制表示一旦將某個哈希 ID 分配給某個特定的提交,這意味著提交永遠存在每個 Git 存盤庫中換句話說,這些提交哈希 ID 是普遍唯一的。1 Git 在這個原則上做了很多事情:例如,我們用git fetchor將兩個 Git 存盤庫相互連接起來git push,它們只交換原始哈希 ID,并立即知道另一個 Git 需要獲取哪些提交(以及檔案) .

  • 是不可變的:任何提交的任何部分都不能改變。(Git 的所有內部物件都是如此,所有這些物件都使用 UUID 散列方案。散列僅在物件不能更改時才有效。)

  • 存盤兩件事:所有檔案的快照(采用特殊的內部只讀重復資料洗掉格式)和一些元資料。元資料包括諸如誰進行了提交以及何時提交等內容,但對于 Git 的內部作業至關重要,還包括先前提交提交的哈希 ID 串列

通常每個提交中的父級串列只有一個元素長,這為我們提供了一個簡單的線性向后看的提交鏈:

... <-F <-G <-H

這里H代表鏈中最后一次提交的實際哈希 ID CommitH存盤所有檔案的快照(截至某人制作時的狀態H)和一些元資料。中的元資料H保存了H的父提交的哈希 ID G,其中存盤了快照和一些元資料;用于G存盤 的哈希 ID的元資料F,其中存盤快照和元資料;以此類推,永遠——或者至少,直到我們回到第一個提交,它不能有父級,所以沒有:

A--B--C--D--E--F--G--H   <-- latest

我們說 commitH向后指向G,向后指向F,依此類推。CommitA是第一個提交,它不指向任何地方,因此可以git log停止。

但是,找到 H,我們必須告訴 Git 它的哈希 ID。為了避免自己記住哈希 ID,我們讓Git將此哈希 ID 保存在一個名稱中,例如分支名稱,latest. 然后該名稱指向H,這讓我們開始。


1我們可以通過鴿巢原理證明這實際上是行不通的。最終它失敗。哈希 ID 的大小決定了失敗多快成為明顯的概率;通過把它做得足夠大,我們將失敗推到了我們不在乎的足夠遠的未來,因為從凱恩斯的長期來看,我們都死了。??


現在我們可以看到分支名稱是如何作業的

假設我們有一系列以 結尾的提交H,加上一個分支名稱,例如main

...--G--H   <-- main

We now add a second name, also pointing to H, so that all the commits are now on two branches:

...--G--H   <-- dev, main

We need a way to pick out which name we're actually using. To do that, we'll have Git attach the special name HEAD to one of the branch names:

...--G--H   <-- dev, main (HEAD)

This means we're "on" main, having done a git checkout main or git switch main, or having started out on main. Meanwhile we're using commit H. If we'd like to use the name dev instead, we run:

git switch dev

and get:

...--G--H   <-- dev (HEAD), main

We're still using commit H, but we're using it through the name dev now.

A brief aside on Git's index / staging-area and your working tree

All the files in any Git commit snapshot are immutable. But we want to be able to mutate files: we can't get any actual new work done if we can't change the files. Git solves this problem like most version control systems: when we check out some commit, Git copies the files out of the commit into a work area. This work area is our working tree or work-tree.

It's important to realize that these files are not in Git. They came out of Git, but inside Git, they are in a special, read-only, compressed (sometimes highly compressed) and de-duplicated form, that only Git itself can read and literally nothing can write. So Git copies them out, and the copies are not in Git. The copies are instead ordinary everyday files, that every program can read and write in the usual way.

When programs do this, Git does not know that they are doing this.2 That's part of why you have to tell Git—with git add—that some file is updated.

Other version control systems have, historically, just scanned for changes. That is, you run their equivalent of checkout and they check out some commit or file. Then you run their equivalent of checkin / commit, and they scan everything, and you go out to lunch because this step will take at least 5 minutes and perhaps an hour or more. Git doesn't do this: instead, Git keeps an extra copy of every file, but in the compressed-and-de-duplicated form. Since these extra copies just came out of a commit, they are by definition duplicates, and therefore take no space.3 This makes up most of what Git calls its index or staging area.

When you run git add on some file, you're really telling Git: Read the working tree copy, and compress it into the internal de-duplicated form. If that turns out to be a duplicate, de-duplicate it now, so that it's prepared for the next commit. Otherwise prepare it for the next commit now. Either way, after git add, the index / staging-area copy now matches the working-tree copy, and is "staged for commit". If it matches the already-committed copy, Git doesn't say anything about it when you run git status. If not, git status says staged for commit. But in fact every file in Git's index is staged for commit: that's why this is the staging area. If Git said updated in proposed next commit, that might be better, but instead Git just says staged for commit.


2For efficiency, it's sometimes nice to use an OS's file-monitoring facilities, and Git has some primitive ability to do this on some OSes. But for the most part Git still isn't aware of this. Git has a different efficiency trick up its sleeves (if Git can be said to have sleeves).

3These index entries still take space to record their names and a bunch of related data, on the rough order of about 100 bytes per file.


Making new commits

Let's say we are in this state:

...--G--H   <-- dev (HEAD), main

That is, we're on branch dev and using commit H. Meanwhile we've updated some files and run git add on them, so that the staged-for-commit copy doesn't match the copy in commit H. We now run git commit, and Git executes the following steps, in some order:

  • Git collects any extra metadata it needs, such as our name and email address and the current date-and-time, and a log message.
  • Git resolves the current commit to a raw hash ID (that of H) to put in as the list of parent commits.
  • Git freezes for all time the snapshot as it appears in the index.
  • Git combines all of these into a new commit, which gets a new unique hash ID; we'll call that I. Note that new commit I points back to existing commit H.
  • Here's the tricky part: Git writes the new commit's hash ID into the current branch name.

So now we have:

          I   <-- dev (HEAD)
         /
...--G--H   <-- main

Note that git branch did not create a branch; git commit created the branch. At least, that's what happened as long as "the branch" means the fact that commit I, now exclusively on dev, "branches off" from main.

As we make more commits, they add on to I:

          I--J   <-- dev (HEAD)
         /
...--G--H   <-- main

until we git switch back to main:

          I--J   <-- dev
         /
...--G--H   <-- main (HEAD)

When we do switch commits, Git removes, from the working tree (and its index / staging-area), the files from commit J, and puts in the files from commit H instead. There's a bunch more trickiness here, but we'll ignore that.

If we create a third name and switch to that, and add two more commits, we get this situation:

          I--J   <-- dev
         /
...--G--H   <-- main
         \
          K--L   <-- feature (HEAD)

It's important to realize two things here:

  1. Commits up through and including H are on all branches.
  2. The name main is no longer needed in some sense: its purpose is to locate commit H. It still serves this purpose, but so do commits J and L. By starting at dev (J) and working backwards, we will reach—and hence find—commit H. The same holds for commit L. However, we do need the names dev and feature because those names are the only ways to find commits I-J and K-L respectively.4

4If you goof this up—which is easy to do in Git—Git provides numerous ways to find the commits again, for a while. Eventually those "recover from mistake" entries, called reflogs, will expire. In what is probably a mistake, that has not been corrected in 15 years, deleting a branch name deletes the branch's reflog, so one should be at least somewhat cautious about branch-name deletion. If Git kept these reflogs, and there's work going on that might lead to this, you could "un-delete" a branch name.


True merges

Once we have a branch-y structure of commits—a commit graph with a branch in it—like this one:

          I--J   <-- br1 (HEAD)
         /
...--G--H
         \
          K--L   <-- br2

we often find it interesting and useful to use git merge. What git merge does with these, expressed as a high-level goal, is to combine work. "Work", in this case, is defined in terms of changes. Git doesn't store changes: Git stores commits. So to get changes, Git has to compare commits.

We already see this every day with git show or git log -p. When we use these commands, Git finds a commit and uses that commit's metadata to find the commit's parent commit:

...--o--o--P--C--o--...

To "show" commit C, Git finds its parent P, extracts both snapshots, and compares them. For every file that is the same, Git says nothing, and for every file that is different, Git figures out a recipe that will change the copy of that file in P to match the copy in C and produces that recipe.

If work is changes, and if we have:

          I--J   <-- br1 (HEAD)
         /
...--G--H
         \
          K--L   <-- br2

then it's intuitively obvious5 that if we compare the snapshot in H to that in J, we'll find out what work happened on br1. If we compare the snapshot in H to that in L, we'll find out what work happened on br2. Moreover, this produces two change recipes, as it were, that if applied to H, produce the snapshots in J and L respectively. If we combine the two recipes, we'll combine the work.

That is, suppose one recipe says to modify some file, and the other doesn't mention the file at all. The combination is to take the change. If both recipes say to change a shared file, we simply combine both changes: as long as they're to different regions of the file, we can probably do that. We'll skip right over the entire mechanism here and just assume that Git can combine changes and do so correctly.6 Git applies the combined changes to the common-starting-point snapshot, from H, and makes a new merge commit M:

          I--J
         /    \
...--G--H      M   <-- br1 (HEAD)
         \    /
          K--L   <-- br2

Commit M has a snapshot as usual: the snapshot is that built by applying the combined changes to the snapshot from H. Commit M has metadata as usual: you are the author-and-committer, its date-and-time is "now", and its default log message is the rather useless7 merge branch br2 into br1. The only thing that is different and special about M is that instead of one parent J, it has two: J and L. So when git log goes looking at what commits are "on" branch br1, Git will follow both links, and commits L and `K will be on the branch now, even though they were not, a moment ago.

If we don't ever need to find commits K-L quickly any more, we can now delete the name br2:

          I--J
         /    \
...--G--H      M   <-- br1 (HEAD)
         \    /
          K--L

We can still find commit L by stepping back to the second parent of M, and from there we can find K. So we might delete the name br1. If we don't, we get the problem you wrote the post about in the first place.


5Mathematicians use this phrase to mean I don't want to prove it, and if I put it this way, you'll be too embarrassed to ask me to do that. ??

6As dumb as Git is—it has no knowledge of the contents of the files; it just applies simple line-by-line text rules here—this actually works surprisingly often. But this is less true for XML or JSON data; don't let Git combine XML or other structured text without careful inspection or testing, or both.

7This is not always completely useless, but any auto-generated text is rarely going to be as good as something someone actually thinks about. Most people don't normally write good merge messages, though; you can derive useful data by looking at the two parent chains.


Things that are not merges

Suppose that instead of the above branch-y diagram, we have the rather simpler:

          I--J   <-- dev
         /
...--G--H   <-- main (HEAD)

Suppose we now run git merge dev to combine work done on main vs work done on dev. The "work" we did on main will be: whatever is in commit H as compared to the files in commit H. But the files in commit H will, by definition, match the files in commit H. So there's no work done on main that isn't already on main. To that, we want to add the work done on dev, which is what we'll see as a recipe if we diff H vs J.

Git could do this as a regular merge:

          I--J   <-- dev
         /    \
...--G--H------M   <-- main (HEAD)

but if Git did this with the standard merge code, the snapshot in M would exactly match the snapshot in J. Commit M is in some sense not required. We do need it if we want to know that some feature was merged, but we don't need it if we just want to keep track of the commits and all the work.

By default, Git doesn't bother doing a full merge here. Instead, git merge dev just does a git checkout or git switch to commit J, while dragging the branch name forward, like this:

          I--J   <-- dev, main (HEAD)
         /
...--G--H

and then there is no reason not to just draw everything on one line:

...--G--H--I--J   <-- dev, main (HEAD)

We can now safely delete the name dev, as before, leaving no trace of the merge action. If we don't, though, and make more commits on main or otherwise advance the name main, we get:

...--G--H--I--J   <-- dev
               \
                K   <-- main (HEAD)

just as br2 will linger behind br1 after a true merge.

Now we can understand git branch --merged and git branch --no-merged

These commands needsone input: a commit. We pick some commit, like J or K or H or whatever. It then looks at all branch names, or with -r, all remote-tracking names (which I'll cover in a moment). For each such name:

  • the name selects some commit;
  • is that commit "ahead of" or "behind" the commit we picked?

Note that can be both, as is the case with:

          I--J   <-- br1 (HEAD)
         /
...--G--H
         \
          K--L   <-- br2

Here, commit L, found via name br2, is behind br1 or commit J because commits I and J are only on br1. But it's also ahead of br1 because commits K and L are only on br2. With:

...--o--P--C--o--...

commit P is one step behind C and C is one step ahead of P, and there are no complications, but when there is a "branch-y" graph structure, there are these complications.

What --no-merged does is look for any names that find any commits that are "ahead of" the selected commit. So if we select commit H, then git branch --no-merged will show us both names br1 and br2, as both names are ahead of H. But if we select commit J, git branch --no-merged will show us only the name br2, because br1 selects J, which is not ahead of J.

What --merged does is similar, except that it shows us any names where the name selects a commit that is not ahead of the one we pick. Let's use this diagram yet again, but add the name main pointing to H, and switch to main:

          I--J   <-- br1
         /
...--G--H   <-- main (HEAD)
         \
          K--L   <-- br2

The git branch --merged command will, if we pick main / HEAD as the commit, show us only main, because br1 and br2 are both ahead of commit H. Note that --merged counts an "even" branch as merged, and since main selects H, git branch --merged main prints main.

If we pick commit J, though, it will show us the names main and br1, because both of those names pick a commit that is not ahead of commit J. Or, if we pick commit L, it will show us names main and br2.

Remote-tracking names

Git is not just a version control system. It's a distributed (and actually more important here, replicated) version control system. We make copies of repositories with git clone. Each repository contains commits, but each repository also contains these branch names that help us find commits.

When we clone a repository, we copy all of its commits8 and none of its branch names. That is, the names in the repository we copy are private to that particular repository. We can, however, see them while our Git, working on our repository, is hooked up to their Git software that's reading their repository. So our Git takes their <name, hash-ID> pairs and stores them in our repository too, but first it changes the names.

We give their repository a name. The standard name we use for "the" other repository (when there's only one such) is origin. That is, we run:

git clone -o origin <url>

and our Git saves the URL under the name origin. If we don't use -o, the default name is origin anyway, so we mostly don't use -o. In any case, this name—which is almost always origin, though you can change it—is something Git calls a remote. It's mainly a short name by which we can refer to their repository, instead of typing out the URL repeatedly.9 I like to refer to this as "their Git": their Git software answers at this URL, which connects their Git software to their repository, or "their Git".

To build the names it will use to save their branch names, our Git sticks our remote name in front of their Git's branch names: their main becomes our origin/main, for instance, and their dev becomes our origin/dev. So after git clone, we have a repository with all the commits, and with all their branch names changed into these funny origin-prefixed names. These names correspond to their branch names, but they literally are not branch names: if you git checkout origin/dev your Git tells you that it's gone into "detached HEAD" mode.

Having done all this copying, the last step of git clone is that our Git will create one branch name. We pick the branch name with -b: git clone -b dev url for instance. If we don't pick a name with -b, our Git will ask their Git what they recommend, which is usually master or main, and then our Git creates that name.

What all this means is that we end up with a repository with all their commits (but see footnote 8) and one branch. Their branches have become our remote-tracking names. Our one branch, that git clone created as its last step, points to the same commit as one of their branch names, and that's the branch we have checked out right now.

To update our remote-tracking names, we run git fetch:

git fetch origin

This tells our Git to look up the name origin, convert it to a URL, contact the Git software there, and have them list out their branch names and hash IDs. Our Git can immediately tell, from the hash IDs, whether we have all of their commits, or need to get some commits from them. If we need commits, our Git converses with their Git to make a more complete list, then gets their new commits and stuffs those into our repository: because these are the same commits, they have the same hash IDs. Now we have all their commits, plus any commits we had before that they didn't have.

Having obtained from them any new commits they have that we need, our Git now updates our remote-tracking names to remember which commits their branch names remember. And then we're done fetching and our Git disconnects from their Git.

(If we want to send them commits that we have that they don't, we use git push. This is almost a mirror image of git fetch, with one really huge exception: they don't have any remote-tracking names for us. We ask them to create or set one of their branch names, after we send them new commits. But we'll skip over all of this here.)


8This is a bit of an overstatement: we copy the reachable commits, and we can deliberately limit how many of those we copy too. But the default is to copy all reachable commits, and people generally don't worry about nominally-removed, still-findable-by-reflog commits, so saying "all commits" is a good way to think of it, as long as you remember that there's a footnote.

9In primeval Git, you really did have to type out the URL each time. This was pretty error-prone and the Git folks invented a bunch of different hacks to get around it. The one that really stuck, in the end, was this idea of a remote, origin.


Conclusion

The git branch command is the user-facing (or porcelain) command that iterates over branch names, or things that look like branch names such as remote-tracking names. It also lets us create and delete branch names, though that's not what we're concerned with here.

Using --merged or --no-merged, we can pick out one commit in our repository, and ask which names—branch and/or remote-tracking names—in our repository point to specific commits that are either not ahead of (--merged) or are ahead of (--no-merged) the one commit we picked out. Because of the nature of the commit graph and the way branch names work, that usually gets us what we want here.

(請注意,我們上面沒有介紹的所謂的squash merge根本不是合并,因此如果有人一直在使用 squash merge,這將不起作用。)

uj5u.com熱心網友回復:

除了toreks 驚人的答案,我偶然發現了這個- 找出“過時”的分支真的分解為

git branch -r | xargs -t -n 1 git branch -r --contains

我想出了一個 PowerShell 片段,git branch --merged它可以集成到基于豪華的環境中:

[CmdletBinding()]
param (
  # path to local git repository
  [Parameter(Mandatory)]
  [string]
  $Path,

  # the branches (regex) in this list will be ignored
  [Parameter(Mandatory = $False)]
  [string[]]
  $IgnoreBranches = @('main', 'master', 'dev', 'develop', '^. _Maintenance$')
)
$ErrorActionPreference = 'Stop'

function Exec {
  [CmdletBinding()]
  param (
    [Parameter(Mandatory, ValueFromPipeline)]
    [scriptblock]
    $ScriptBlock
  )
  $LASTEXITCODE = 0
  try {
    & $ScriptBlock
    $theEc = $LASTEXITCODE
  }
  finally {
    if ($theEc -ne 0) {
      Write-Error "expected 0 exit code, got $theEc"
      Write-Error $ScriptBlock.ToString()
      throw "command exited with $theEc"
    }
  }
}

Push-Location $Path
try {

  # ensure we're not analyzing a shallow checkout, prune branches deleted on remote
  Exec { git fetch --prune }

  # get list of all branches that exist on remote
  $remoteBranches = (Exec { git branch -r }).Trim()

  # map used to store wich branches are fully contained in other branches (b -> fully contained in (a,c,d))
  # string -> string[]
  $fullyContainedBranches = @{}

  # foreach branch, figure out what other branches are "fully contained" -> candidates for deletion
  foreach ($b in $remoteBranches) {
    $b = $b.Split(' ')[0]
    Write-Verbose " checking fully integrated branches of '$b'"
    $fullyContained = Exec { git branch -r --merged $b }
    
    if (-not $fullyContained) {
      Write-Verbose "  '$b' is already gone for good!"
      $fullyContainedBranches[$b] = @()
      continue
    }

    foreach ($f in $fullyContained) {
      $f = $f.Replace('* ', '').Trim()
      Write-Verbose "   -> '$f' is in '$b'"
        
      if (-not $fullyContainedBranches[$f]) {
        $fullyContainedBranches[$f] = @()
      }

      $fullyContainedBranches[$f]  = $b
    }
  }

  
  $fullyContainedBranches.Keys | Foreach-Object {
    $branchName = $_

    if ($IgnoreBranches) {
      if (($IgnoreBranches | ForEach-Object { $branchName -match $_ }) -contains $true) {
        Write-Verbose "ignoring $branchName"
        return
      }
    }
    # put output objects to pipeline
    @{
      branch       = $branchName
      contained_in = $fullyContainedBranches[$branchName]
    }
  }
}
finally {
  Pop-Location
}

轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/409102.html

標籤:

上一篇:我需要更好地理解Gitpulloriginmaster--allow-unrelated-histories

下一篇:如何創建具有兩個位置的git子模塊?

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • JAVA使用 web3j 進行token轉賬

    最近新學習了下區塊鏈這方面的知識,所學不多,給大家分享下。 # 1. 關于web3j web3j是一個高度模塊化,反應性,型別安全的Java和Android庫,用于與智能合約配合并與以太坊網路上的客戶端(節點)集成。 # 2. 準備作業 jdk版本1.8 引入maven <dependency> < ......

    uj5u.com 2020-09-10 03:03:06 more
  • 以太坊智能合約開發框架Truffle

    前言 部署智能合約有多種方式,命令列的瀏覽器的渠道都有,但往往跟我們程式員的風格不太相符,因為我們習慣了在IDE里寫了代碼然后打包運行看效果。 雖然現在IDE中已經存在了Solidity插件,可以撰寫智能合約,但是部署智能合約卻要另走他路,沒辦法進行一個快捷的部署與測驗。 如果團隊管理的區塊節點多、 ......

    uj5u.com 2020-09-10 03:03:12 more
  • 谷歌二次驗證碼成為區塊鏈專用安全碼,你怎么看?

    前言 谷歌身份驗證器,前些年大家都比較陌生,但隨著國內互聯網安全的加強,它越來越多地出現在大家的視野中。 比較廣泛接觸的人群是國際3A游戲愛好者,游戲盜號現象嚴重+國外賬號安全應用廣泛,這類游戲一般都會要求用戶系結名為“兩步驗證”、“雙重驗證”等,平臺一般都推薦用谷歌身份驗證器。 后來區塊鏈業務風靡 ......

    uj5u.com 2020-09-10 03:03:17 more
  • 密碼學DAY1

    目錄 ##1.1 密碼學基本概念 密碼在我們的生活中有著重要的作用,那么密碼究竟來自何方,為何會產生呢? 密碼學是網路安全、資訊安全、區塊鏈等產品的基礎,常見的非對稱加密、對稱加密、散列函式等,都屬于密碼學范疇。 密碼學有數千年的歷史,從最開始的替換法到如今的非對稱加密演算法,經歷了古典密碼學,近代密 ......

    uj5u.com 2020-09-10 03:03:50 more
  • 密碼學DAY1_02

    目錄 ##1.1 ASCII編碼 ASCII(American Standard Code for Information Interchange,美國資訊交換標準代碼)是基于拉丁字母的一套電腦編碼系統,主要用于顯示現代英語和其他西歐語言。它是現今最通用的單位元組編碼系統,并等同于國際標準ISO/IE ......

    uj5u.com 2020-09-10 03:04:50 more
  • 密碼學DAY2

    ##1.1 加密模式 加密模式:https://docs.oracle.com/javase/8/docs/api/javax/crypto/Cipher.html ECB ECB : Electronic codebook, 電子密碼本. 需要加密的訊息按照塊密碼的塊大小被分為數個塊,并對每個塊進 ......

    uj5u.com 2020-09-10 03:05:42 more
  • NTP時鐘服務器的特點(京準電子)

    NTP時鐘服務器的特點(京準電子) NTP時鐘服務器的特點(京準電子) 京準電子官V——ahjzsz 首先對時間同步進行了背景介紹,然后討論了不同的時間同步網路技術,最后指出了建立全球或區域時間同步網存在的問題。 一、概 述 在通信領域,“同步”概念是指頻率的同步,即網路各個節點的時鐘頻率和相位同步 ......

    uj5u.com 2020-09-10 03:05:47 more
  • 標準化考場時鐘同步系統推進智能化校園建設

    標準化考場時鐘同步系統推進智能化校園建設 標準化考場時鐘同步系統推進智能化校園建設 安徽京準電子科技官微——ahjzsz 一、背景概述隨著教育事業的快速發展,學校建設如雨后春筍,隨之而來的學校教育、管理、安全方面的問題成了學校管理人員面臨的最大的挑戰,這些問題同時也是學生家長所擔心的。為了讓學生有更 ......

    uj5u.com 2020-09-10 03:05:51 more
  • 位元幣入門

    引言 位元幣基本結構 位元幣基礎知識 1)哈希演算法 2)非對稱加密技術 3)數字簽名 4)MerkleTree 5)哪有位元幣,有的是UTXO 6)位元幣挖礦與共識 7)區塊驗證(共識) 總結 引言 上一篇我們已經知道了什么是區塊鏈,此篇說一下區塊鏈的第一個應用——位元幣。其實先有位元幣,后有的區塊 ......

    uj5u.com 2020-09-10 03:06:15 more
  • 北斗對時服務器(北斗對時設備)電力系統應用

    北斗對時服務器(北斗對時設備)電力系統應用 北斗對時服務器(北斗對時設備)電力系統應用 京準電子科技官微(ahjzsz) 中國北斗衛星導航系統(英文名稱:BeiDou Navigation Satellite System,簡稱BDS),因為是目前世界范圍內唯一可以大面積提供免費定位服務的系統,所以 ......

    uj5u.com 2020-09-10 03:06:20 more
最新发布
  • web3 產品介紹:metamask 錢包 使用最多的瀏覽器插件錢包

    Metamask錢包是一種基于區塊鏈技術的數字貨幣錢包,它允許用戶在安全、便捷的環境下管理自己的加密資產。Metamask錢包是以太坊生態系統中最流行的錢包之一,它具有易于使用、安全性高和功能強大等優點。 本文將詳細介紹Metamask錢包的功能和使用方法。 一、 Metamask錢包的功能 數字資 ......

    uj5u.com 2023-04-20 08:46:47 more
  • Hyperledger Fabric 使用 CouchDB 和復雜智能合約開發

    在上個實驗中,我們已經實作了簡單智能合約實作及客戶端開發,但該實驗中智能合約只有基礎的增刪改查功能,且其中的資料管理功能與傳統 MySQL 比相差甚遠。本文將在前面實驗的基礎上,將 Hyperledger Fabric 的默認資料庫支持 LevelDB 改為 CouchDB 模式,以實作更復雜的資料... ......

    uj5u.com 2023-04-16 07:28:31 more
  • .NET Core 波場鏈離線簽名、廣播交易(發送 TRX和USDT)筆記

    Get Started NuGet You can run the following command to install the Tron.Wallet.Net in your project. PM> Install-Package Tron.Wallet.Net 配置 public reco ......

    uj5u.com 2023-04-14 08:08:00 more
  • DKP 黑客分析——不正確的代幣對比率計算

    概述: 2023 年 2 月 8 日,針對 DKP 協議的閃電貸攻擊導致該協議的用戶損失了 8 萬美元,因為 execute() 函式取決于 USDT-DKP 對中兩種代幣的余額比率。 智能合約黑客概述: 攻擊者的交易:0x0c850f,0x2d31 攻擊者地址:0xF38 利用合同:0xf34ad ......

    uj5u.com 2023-04-07 07:46:09 more
  • Defi開發簡介

    Defi開發簡介 介紹 Defi是去中心化金融的縮寫, 是一項旨在利用區塊鏈技術和智能合約創建更加開放,可訪問和透明的金融體系的運動. 這與傳統金融形成鮮明對比,傳統金融通常由少數大型銀行和金融機構控制 在Defi的世界里,用戶可以直接從他們的電腦或移動設備上訪問廣泛的金融服務,而不需要像銀行或者信 ......

    uj5u.com 2023-04-05 08:01:34 more
  • solidity簡單的ERC20代幣實作

    // SPDX-License-Identifier: GPL-3.0 pragma solidity >=0.7.0 <0.9.0; import "hardhat/console.sol"; //ERC20 同質化代幣,每個代幣的本質或性質都是相同 //ETH 是原生代幣,它不是ERC20代幣, ......

    uj5u.com 2023-03-21 07:56:29 more
  • solidity 參考型別修飾符memory、calldata與storage 常量修飾符C

    在solidity語言中 參考型別修飾符(參考型別為存盤空間不固定的數值型別) memory、calldata與storage,它們只能修飾參考型別變數,比如字串、陣列、位元組等... memory 適用于方法傳參、返參或在方法體內使用,使用完就會清除掉,釋放記憶體 calldata 僅適用于方法傳參 ......

    uj5u.com 2023-03-08 07:57:54 more
  • solidity注解標簽

    在solidity語言中 注釋符為// 注解符為/* 內容*/ 或者 是 ///內容 注解中含有這幾個標簽給予我們使用 @title 一個應該描述合約/介面的標題 contract, library, interface @author 作者的名字 contract, library, interf ......

    uj5u.com 2023-03-08 07:57:49 more
  • 評價指標:相似度、GAS消耗

    【代碼注釋自動生成方法綜述】 這些評測指標主要來自機器翻譯和文本總結等研究領域,可以評估候選文本(即基于代碼注釋自動方法而生成)和參考文本(即基于手工方式而生成)的相似度. BLEU指標^[^?88^^?^]^:其全稱是bilingual evaluation understudy.該指標是最早用于 ......

    uj5u.com 2023-02-23 07:27:39 more
  • 基于NOSTR協議的“公有制”版本的Twitter,去中心化社交軟體Damus

    最近,一個幽靈,Web3的幽靈,在網路游蕩,它叫Damus,這玩意詮釋了什么叫做病毒式營銷,滑稽的是,一個Web3產品卻在Web2的產品鏈上瘋狂傳銷,各方大佬紛紛為其背書,到底發生了什么?Damus的葫蘆里,賣的是什么藥? 注冊和簡單實用 很少有什么產品在用戶注冊環節會有什么噱頭,但Damus確實出 ......

    uj5u.com 2023-02-05 06:48:39 more